Wortsuchlöser

13

Ich habe mich gestern gefragt, ob ich ein Programm schreiben könnte, um eine gegebene Wortsuche durchzukämmen und die Antworten auszugeben. Es war eigentlich überraschend einfach. Jetzt frage ich mich, wie klein wir werden können.

Regeln

  • Ihre erste Eingabe ist eine Zeichenfolge oder eine Sammlung von n Zeilen, von denen jede n Zeichen lang ist
  • Ihre zweite Eingabe ist eine Liste von Wörtern in jedem Format, die im Puzzle zu finden sind
  • Alle Wörter in der Suchliste sind garantiert im Puzzle
  • Wörter können in jede der vier Hauptrichtungen sowie diagonal vorwärts und rückwärts ausgerichtet werden
  • Das Puzzle enthält nur Großbuchstaben von AZ
  • Ihr Code muss jedes Wort in der Suchzeichenfolge finden und die Koordinatenposition des Anfangsbuchstabens ausgeben, wobei 0,0 das Zeichen oben links ist.
  • Falls Sie mehr als eine Instanz desselben Wortes finden, können Sie damit umgehen, wie Sie möchten. Geben Sie es mehrmals oder nur einmal aus, es liegt an Ihnen

Beispiele / Testfälle

Angesichts der folgenden Tafel:

ABCD
EFGH
IJKL
MNOP

Und der folgende Suchbegriff:

ABCD,CGKO,POMN,NJF,AFKP,CFI,LGB,MJGD

Ihr Programm sollte in beliebiger Reihenfolge Folgendes ausgeben:

ABCD at 0,0
CGKO at 0,2
PONM at 3,3
NJF at 3,1
AFKP at 0,0
CFI at 0,2
LGB at 2,3
MJGD at 3,0

Wie immer gewinnt die kürzeste Antwort

morpen
quelle
6
Willkommen bei PPCG! Schöne erste Herausforderung!
AdmBorkBork
2
Ähnlich scheint der einzige wirkliche Unterschied darin zu bestehen, dass die Position in die Ausgabe einbezogen wird.
FryAmTheEggman
@ NL628 Ja, alle Suchbegriffe sind garantiert im Puzzle enthalten. Wenn es mehr als ein Ereignis gibt, können Sie es entweder beide Male ausgeben oder das zweite Mal ignorieren, es liegt an Ihnen.
Morpen
@ JonathanAllan Tolle Idee. Ich werde es aktualisieren, wie Sie vorgeschlagen haben.
Morpen
1
@ RickHitchcock Ja, es sollte :)
Morpen

Antworten:

4

JavaScript (Node.js) , 154 152 150 141 Byte

  • Danke an Arnauld für die Reduzierung um 2 Bytes

Gibt ein Array von Positionen zurück (es war zuvor eine Zeichenfolge mit neuen Zeilen)

(b,w)=>w.map(s=>[...b].map((_,p)=>[1,-1,r=b.search`
`,-r,~r,++r,-~r,~r].map(d=>[...s].every((c,i)=>c==b[p+d*i])?s+=" at "+[p/r|0,p%r]:0))&&s)

Probieren Sie es online!

DanielIndie
quelle
3

Python 2 , 213 Bytes

lambda a,W:[(w,i,j)for w in W for i in R(L(a))for j in R(L(a[0]))for U in R(9)if U-4and g(i,j,U/3-1,U%3-1,a).find(w)==0]
g=lambda i,j,u,v,a,s='':L(a)>i>=0<=j<L(a[0])and g(i+u,j+v,u,v,a,s+a[i][j])or s
L=len;R=range

Probieren Sie es online!

gNimmt eine Startposition i,jund eine Richtung u,vund extrahiert durch Rekursion die Zeichenfolge, die an dieser Position in dieser Richtung beginnt.

fbesucht dann jeden Startort i,jund jede Startrichtung U/3-1,U%3-1und überprüft jedes Wort, wum festzustellen, ob die resultierende Zeichenfolge mit beginnt w.

Chas Brown
quelle
2

Python 3 , 149 147 Bytes

def g(b,w):h=b.find('\n')+1;return[f'{y} at {i//h},{i%h}'for y in w for i in range(len(b))for d in(1,h+1,h,h-1,-1,~h,-h,1-h)if y==b[i::d][:len(y)]]

Probieren Sie es online!

Ungolfed-Version

def g(b,w):
    h = b.find('\n') + 1                              # width of a row plus the '\n'
    a = []
    for y in w:                                       # iterate over the words
        for i in range(len(b)):                       #   iterate over the game board
            for d in(1,h+1,h,h-1,-1,~h,-h,1-h):       #     for each possible direction
                if y==b[i::d][:len(y)]:               #       see if the word matches
                    a.append(f'{y} at {i//h},{i%h}')
    return a

Die Hauptidee ist, dass b[i::d]ein Slice vom Spielplan ausgewählt wird. Die Scheibe beginnt als Position iund erstreckt sich in die Richtung d. Entspricht beispielsweise d = h+1der Südostdiagonale, wohingegen d = ~hdie gleiche wie -h-1die Nordwestdiagonale entspricht. [:len(y)] schneidet die Scheibe in der gleichen Länge ab wie das gesuchte Wort.

RootTwo
quelle