Wortsuchrätsel

29

Bestimmen Sie anhand eines rechteckigen Texts als Wortsuchrätsel und einer Suchzeichenfolge, ob der Text die Suchzeichenfolge enthält. Die Suchzeichenfolge wird möglicherweise angezeigt:

  • horizontal, vertikal oder diagonal
  • vorwärts oder rückwärts

Sie können eine Funktion oder ein Programm schreiben und zwei Zeichenfolgen als Eingabe über das Funktionsargument ARGV oder STDIN verwenden. Die Ausgabe sollte ein wahres oder falsches Ergebnis sein, das entweder von der Funktion zurückgegeben oder in STDOUT geschrieben werden kann.

Angenommen, der Text enthält beliebige druckbare ASCII-Zeichen (Hex-Codes 20 bis 7E) und Zeilenumbruchzeichen. Buchstaben unterscheiden zwischen Groß- und Kleinschreibung. Sie können davon ausgehen, dass der Eingabetext rechteckig ist, dh alle Zeilen haben die gleiche Länge. Sie können festlegen, ob die Eingabe mit einem abschließenden Zeilenumbruch endet oder nicht (sofern dies für Ihre Übermittlung von Bedeutung ist).

Dies ist Code Golf, die kürzeste Antwort (in Bytes) gewinnt.

Beispiele

Verwenden dieses Rasters aus dem Wikipedia-Artikel zur Wortsuche als erste Eingabe:

WVERTICALL
ROOAFFLSAB
ACRILIATOA
NDODKONWDC
DRKESOODDK
OEEPZEGLIW
MSIIHOAERA
ALRKRRIRER
KODIDEDRCD
HELWSLEUTH

Die folgenden Suchzeichenfolgen sollten zutreffende oder falsche Ergebnisse liefern:

Truthy: RANDOM, VERTICAL, HORIZONTAL, WORDSEARCH, WIKIPEDIA, TAIL
Falsy:  WordSearch, CODEGOLF, UNICORN

Alternativ können Sie diesen Eingabetext verwenden

Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur.

Wir erhalten die folgenden Suchergebnisse (verwenden jetzt Anführungszeichen, da einige Suchzeichenfolgen Leerzeichen enthalten):

Truthy: "Lorem", "mine", "uma bop", "tuetdod", "snol,a", "texas", "pii.d  v", "vexta"
Falsy:  "lorem", "wordsearch", "pii.d v", "mute"
Martin Ender
quelle

Antworten:

7

CJam, 46 37 Bytes

qN%{_zW%__,N**2$2$+,)/z\}4*]:+N*eas#)

Liest das Raster von STDIN und das Wort als Befehlszeilenargument. Gibt positive Ganzzahlen für Übereinstimmungen und 0 für Nichtübereinstimmungen aus.

Gegen zwei zusätzliche Bytes können beide Strings (Word, Linefeed, Grid) von STDIN gelesen werden:

qN%(\{_zW%__,N**2$2$+,)/z\}4*](\:+N*\#)

Sie können diese Version online mit dem CJam-Interpreter testen .

Beispiellauf

$ for W in Lorem mine uma\ bop tuetdod snol,a texas pii.d\ \ v vexta WordSearch CODEGOLF UNICORN; do echo -e "$(cjam wordsearch.cjam "$W" < grid)\t$W"; done
1       Lorem
3085    mine
2055    uma bop
5142    tuetdod
3878    snol,a
1426    texas
5371    pii.d  v
2536    vexta
0       WordSearch
0       CODEGOLF
0       UNICORN

Hintergrund

Angenommen, die Eingabe war das folgende Raster:

ABCD
EFGH
IJKL

Bei der Aufteilung bei Zeilenvorschüben erhalten wir das folgende Array:

A := [
         "ABCD"
         "EFGH"
         "IJKL"
     ]

Dies umfasst Ostwörter (Wörter von links nach rechts).

Jetzt verbinden wir die Elemente der AVerwendung einer Zeichenfolge von len(A)Zeilenumbrüchen als Trennzeichen:

"ABCD⏎⏎⏎EFGH⏎⏎⏎IJKL"

Dann hacken wir die resultierende Zeichenfolge in Stücke von Länge len(A) + len(A[0]) + 1:

[
    "ABCD⏎⏎⏎E"
    "FGH⏎⏎⏎IJ"
    "KL"
]

Wenn wir das Array "zip" (Zeilen und Spalten transponieren), erhalten wir:

[
    "AFK"
    "BGL"
    "CH"
    "D⏎"
    "⏎⏎"
    "⏎⏎"
    "I⏎"
    "EJ"
]

Das deckt Südostwörter ab.

Wenn wir A komprimieren und die Reihenfolge der Ergebniszeilen umkehren, erhalten wir:

[
    "DHL"
    "CGK"
    "BFJ"
    "AEI"
]

Das deckt den Süden und - nach Wiederholung des Prozesses für Diagonalen - den Südwesten ab.

Durch erneutes Zippen und Umkehren erhalten wir:

[
    "LKJI"
    "HGFE"
    "DCBA"
]

Das deckt West und - nach Wiederholung des Prozesses für Diagonalen - Nordwestwörter ab.

Durch erneutes Zippen und Umkehren erhalten wir:

[
    "IEA"
    "JFB"
    "KGC"
    "LHD"
]

Das deckt Norden und - nach Wiederholung des Prozesses für Diagonalen - Nordostwörter ab.

Wie es funktioniert

Der Code funktioniert wie im vorherigen Abschnitt erläutert, mit zwei geringfügigen Unterschieden:

  • Es reißt einmal ganz am Anfang und dreht sich um.
  • Es berechnet len(A) + len(A[0])als len(A + zip(A)).

Schließlich werden alle Zeilen aller generierten Arrays mithilfe von Zeilenvorschüben als Trennzeichen verbunden und in der resultierenden Zeichenfolge nach dem Wort gesucht.

qN%                                   " A := split(input(),'\n')                          ";
   {                    }4*           " Do 4 times:                                       ";
    _zW%                              "   B := reverse(zip(A))                            ";
        __,N**                        "   C := B.join(len(B) * '\n')                      ";
              2$2$+,)/z               "   D := zip(C.chunks(len(A + B) + 1))              ";
                       \              "   A := B                                          ";
                           ]          " Collect all values of A and D in an array R.      ";
                            :+        " R := flatten(R)                                   ";
                              N*      " R := R.join('\n')                                 ";
                                eas   " I := flatten(ARGV)                                ";
                                   #) " print R.index(I) + 1                              ";
Dennis
quelle
7

Java: 183 211 321

boolean s(char[]w,char[]s){int j,z,a=s.length,i=a*9,f=1,q=0;for(;s[q++]>10;);for(;i-->0;)for(j=w.length,z=i/9;i%9!=4&j-->0&z>=0&z<a&&s[z]==w[j];z+=q*(i/3%3)+i%3-q-1)f*=j;return f==0;}

Eine grundlegende rohe Kraft. Es gibt wohl nicht viel mehr zu sagen. Die Eingabe erfolgt zuerst mit der Nadel und dann mit dem Heuhaufen. Angenommen, das Raster ist mit Zeilenumbruch beendet .

Eine etwas besser lesbare Version mit dem gezeigten Testfall:

public class WordSearch {
    static String grid = "WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH";
    static String search = "RANDOM";

    public static void main(String[] args) {
        System.out.println(new WordSearch().s(search.toCharArray(),grid.toCharArray()));
    }

    boolean s(char[]w,char[]s){
        int j,z,a=s.length,i=a*9,f=1,q=0;
        for(;s[q++]>10;);
        for(;i-->0;)
            for(j=w.length,z=i/9;
                i%9!=4&j-->0&z>=0&z<a&&s[z]==w[j];
                z+=q*(i/3%3)+i%3-q-1)
                f*=j;
        return f==0;
    }
}
Geobits
quelle
if(e<1)return 1>0;könnte es return e<1;nicht sein?
FryAmTheEggman
@FryAmTheEggman Nein, das würde zurückkehren, nachdem der erste Fehler gefunden wurde, sodass nicht das gesamte Raster durchsucht würde.
Geobits
1
Ah sorry, hab mich da irgendwie verlaufen; _;
FryAmTheEggman
4
Die out two for-Schleifen könnten stattdessen zu einer zusammengefasst werden, also tun Sie i=a*9,und for(;i-->0;)und dann z=i/9;und i%a!=4&und so weiter?
Will
1
Wow, das ist so ähnlich wie meins. Und ich habe es erst angeschaut, nachdem ich bereits angefangen hatte. Ich habe mir keine Zeit genommen, um zu sehen, wie es funktioniert. +1.
Level River St
6

JavaScript (E6) 111 116

Brute-Force-Suche nach jedem Charakter in jede Richtung - so gut ich kann

F=(b,w)=>
  [1,-1,r=b.search('\n'),-r,++r,-r,++r,-r].some(d=>
    [...b].some((_,p)=>
      [...w].every(c=>c==b[p+=d],p-=d)
    )
  )

Test In FireFox / Firebug - Konsole

;["RANDOM", "VERTICAL", "HORIZONTAL", "WORDSEARCH", "WIKIPEDIA", "TAIL",
"WordSearch", "CODEGOLF", "UNICORN"]
.forEach(w=>console.log('\n'+ w +' -> '+
  F("WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH",w)))

Ausgabe

RANDOM -> true
VERTICAL -> true
HORIZONTAL -> true
WORDSEARCH -> true
WIKIPEDIA -> true
TAIL -> true
WordSearch -> false
CODEGOLF -> false
UNICORN -> false
edc65
quelle
5

Python, 175

Nicht sehr inspiriert, aber hier geht:

def s(h,n):
 l=h.find('\n')+2;h+='\n'*l;L=i=len(h)
 while i>0:
  i-=1
  for d in[-l,1-l,2-l,-1,1,l-2,l-1,l]:
    j=i;m=len(n)
    for c in n:m-=c==h[j%L];j+=d
    if m<1:i=-1
 return-i

Das erste Argument ist Heuhaufen, das zweite ist Nadel.

Ell
quelle
Ich denke, Sie können 6 Zeichen mit h,n=input()und speichern print. Funktioniert dies auch mit nicht quadratischen Eingaben? (m = len (n)? Ich gebe zu, nicht vollständig zu verstehen, was Sie tun, so könnte ich völlig falsch liegen!)
FryAmTheEggman
@FryAmTheEggman: Ja, es funktioniert mit nicht quadratischen Eingaben.
Ell
1
Einige Standard-Python-Optimierungen: while i>0to while i:(da iniemals negativ werden kann), if m<1:i=-1to i-=m<1.
Xnor
1
@xnor Ich glaube , Sie falsch verstanden haben if m<1:i=-1als if m<1:i-=1wie keiner von denen arbeiten , weil er setzt inegativ.
FryAmTheEggman
@FryAmTheEggman Oh ja, das habe ich total falsch verstanden.
18.
5

Bash + Coreutils, 214 169 Bytes

r()(tee >(rev) $@)
t()(eval paste -d'"\0"' `sed 's/.*/<(fold -1<<<"&")/'`)
d()(while IFS= read l;do echo "$a$l";a+=_;done|t)
r<<<"$2"|r >(d) >(r|t) >(r|d)|r|grep -q "$1"

Verwendet 3 Transformationsfunktionen r, tundd umgekehrt, transponiert und diagonale Verschiebung in allen notwendigen Kombinationen.

Update - Die rFunktion erzeugt jetzt eine invertierte und eine nicht invertierte Ausgabe für zusätzliche Golffreundlichkeit

Eingabe über Befehlszeilenargumente - Suchzeichenfolge, gefolgt von einem (durch Zeilenumbrüche getrennten) rechteckigen Wortsuchblock.

Die Ausgabe ist ein idiomatisch korrekter Shell-Exit-Statuscode - 0 bedeutet TRUE und 1 bedeutet FALSE.

Ausgabe:

$ for w in "Lorem" "mine" "uma bop" "tuetdod" "snol,a" "texas" "pii.d  v" "vexta" ; do ./ws.sh "$w" "Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur."; echo $?; done
0
0
0
0
0
0
0
0
$ for w in WordSearch CODEGOLF UNICORN ; do ./ws.sh "$w" "Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur."; echo $?; done
1
1
1
$ 
Digitales Trauma
quelle
1. Ich wollte vorschlagen T()(tee >(r) $@), aber das ist noch besser. 2. Ich glaube, ich habe diese Funktionssyntax noch nie gesehen. 3. Wenn Sie nicht leere Zeichenfolgen für wahr und leere Zeichenfolgen für falsch halten, können Sie dies meines Erachtens weglassen -q.
Dennis
Wenn du definierst r()(tee >(rev) $@), r<<<"$2"|r >(d) >(r|t) >(r|d)|r|grep "$1"sollte das auch funktionieren.
Dennis
Ich habe nichts anderes getestet, aber die beiden Testfälle in der Frage wurden beim Versuch überprüft.
Dennis
@ Tennis Nice - yep es funktioniert jetzt. Ich habe mich bei Martin erkundigt - er möchte, dass der -qbleibt.
Digital Trauma
5

C 163

f(char*h,char*n){int i,j,d,p,y=0,l=strlen(h),w=strchr(h,10)-h+1;for(i=l*9;i--;y+=d&&!n[j]){p=i/9;d=i%9/3*w-w+i%3-1;for(j=0;p>=0&p<l&h[p]==n[j];j++)p+=d;}return y;}

Keine Neuordnung des Gitters, ich versuche einfach jeden Anfangsbuchstaben in alle Richtungen und gehe weiter, bis ich vom Gitter abkomme oder eine Nichtübereinstimmung finde.

Ich nutze die Tatsache, dass ein C-String in einem Null-Byte endet. Da das Gitter keine Null-Bytes enthält, kommt es IMMER zu einer Nichtübereinstimmung. Wenn die Nichtübereinstimmung jedoch bei dem Null-Byte auftritt, wissen wir, dass wir das Ende der zu suchenden Zeichenfolge gefunden haben, und zeichnen Sie es als Übereinstimmung auf.

Ungolfed in einem Testprogramm

char h[]="WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH\n";

f(char*h,char*n){                                   //haystack,needle
  int i,j,d,p,y=0,l=strlen(h),w=strchr(h,10)-h+1;   //l=length of whole grid. w=width of row, including terminal newline ASCII 10
  for(i=l*9;i--;){                                  //for each start letter and direction
    p=i/9;                                          //pointer to start letter
    d=i%9/3*w-w+i%3-1;                              //9 possible values of direction vector {-w,0,w}+{-1,0,1}
    for(j=0;p>=0&p<l&h[p]==n[j];j++)p+=d;           //walk p in the direction defined by d until we walk off the top or bottom of the grid or a mismatch is fount
    y+=d&&!n[j];                                    //if we got all the way to the terminal 0, record it as a hit. If d=0, don't record as this is an invalid direction.
  }
  return y;   
}

main(int c, char**v){
  printf("%d",f(h,v[1]));  
}

Ausgabe

Beachten Sie, dass die Funktion die Gesamtzahl der Vorkommen der im Raster gesuchten Zeichenfolge zurückgibt. Damit für ODsie gibt 6. Wenn keine Vorfälle gefunden es 0 zurückgibt , die der einzige falsy Wert in C zu ändern y|=d*!n[j]ein Zeichen speichern würde , aber diese Funktionalität verlieren.

$ ./a UNICORN
0

$ ./a CODEGOLF
0

$ ./a WordSearch
0

$ ./a RANDOM
1

$ ./a WORDSEARCH
1

$ ./a VERTICAL
1

$ ./a HORIZONTAL
1

$ ./a WIKIPEDIA
1

$ ./a TAIL
1

$ ./a OD
6
Level River St
quelle
5

C # - 218 197 186 Bytes

C # -Funktion, die zwei Zeichenfolgen verwendet: das erste Wort, nach dem gesucht werden soll, und das spätere Gitter mit Zeilenvorschüben ( \n) zwischen den Zeilen. Die Dinge werden jetzt verzweifelt ... so verzweifelt in der Tat, dass meine vorherige Bearbeitung nicht funktioniert hat!

Golf Code:

bool F(string D,string S){int l=S.Length,i=l*13,r,p;for(S+="\n";i-->l*5;i=r<0?r:i)for(r=D.Length,p=i%l;p>-1&p<l&r-->0&&D[r]==S[p];p+=(S.IndexOf('\n')+1)*(i/l%9/3-1)+i/l%3-1);return i<0;}

Weniger Golf mit Testcode:

class P
{
    static void Main()
    {
        System.Console.WriteLine(new P().F(System.Console.ReadLine(),System.Console.In.ReadToEnd())?"Truthy":"Falsy"); // because why not
    }

    bool F(string D,string S)
    {
        int l=S.Length,i=l*13,r,p;

        for(S+="\n";i-->l*5;i=r<0?r:i) // for each cell/direction
            for(r=D.Length,p=i%l;p>-1&p<l&r-->0&&D[r]==S[p];p+=(S.IndexOf('\n')+1)*(i/l%9/3-1)+i/l%3-1); // test against string (backwards)

        return i<0;
    }
}
VisualMelon
quelle
4

Haskell - 173

Anstatt direkt im Raster zu suchen, transformiere ich das Raster auf unterschiedliche Weise und ordne das Wort jeder Zeile des neuen Rasters zu.

Beispielsweise,

G1    G2    G3       G4   G5

abcd  aA1   abcd     a..  ..1
ABCD  bB2   .ABCD    bA.  .A2
1234  cC3   ..1234   cB1  aB3
      dD4            dC2  bC4
                      D3  cD
                       4  d

Suche das Wort in jeder Zeile von G1, G2, G4 und G5, dann sind wir fertig. Beachten Sie, dass G3 nicht verwendet wird, ich poste es hier nur zur Veranschaulichung.

Eine ähnliche Idee gilt für die Suche vorwärts und rückwärts: Suchen Sie einfach das ursprüngliche Wort und das umgekehrte Wort.

Also haben wir jetzt 8 Richtungen gesucht. Hier ist der Code, dessen Richtigkeit von einem anderen Skript überprüft wurde .

import Data.List
v=reverse
t=transpose
y=any
d r=zipWith(++)(scanr(\_->('\n':))[]r)r
g r w=y(y$y((==w).take(length w)).tails)[r,t r,t.d$r,t.d.v$r]
f r w=y(g(lines r))[w,v w]

Die Funktion fist das, was wir wollen, und ihr Argument rist die rechteckige Zeichenfolge, wdas zu suchende Wort.

Strahl
quelle
4

Python 2 - 246 259 275 308 298 297 294 313 322

w,s=input()
r=range
d='\n'
I=''.join
w=w.split(d)
t,u=len(w),len(w[0])
v=d.join([I(x)for x in zip(*w)]+[d]+[I([w[i+j][i]for i in r(min(u,t-j))])+d+I([w[i][i+j]for i in r(min(t,u-j))])for j in r(max(t,u))]+[d]+w)
print s in v or s[::-1]in v

Vielen Dank an Will für die Hilfe beim Umgang mit dem Druck und beim Definieren des Joins.

Vielen Dank an die U-Bahn, die mich an die richtigen Golfplätze erinnert hat

Bei schlechten Übereinstimmungen behoben, da ',' als Trennzeichen verwendet wurde.

Anscheinend ist der beste Weg zum Golfen das Hinzufügen von Tonnen von horizontalem Scrollen.

Eingabe als Leerzeichen Bang Neue - Zeile begrenzt Linien in Zitate: "WVERTICALL \ nROOAFFLSAB \ nACRILIATOA \ nNDODKONWDC \ nDRKESOODDK \ nOEEPZEGLIW \ nMSIIHOAERA \ nALRKRRIRER \ nKODIDEDRCD \ nHELWSLEUTH", "RANDOM"

FryAmTheEggman
quelle
1
L=len;J=''.joinetc und print any(s in(v,d,w,r...))? Ich war auf dem gleichen Weg, als ich sah, dass du gepostet hast :)
Will
@Will Danke für die Hilfe! Das Definieren von len kostet nur so viele Zeichen, wie es spart, und ich bin nicht sicher, wie Join optimal definiert werden soll (einige haben Kommas), also mache ich es gleich.
FryAmTheEggman
Überall, wo Sie ein Leerzeichen haben )oder von diesem ]gefolgt werden, können Sie das Leerzeichen entfernen.
Undergroundmonorail
2

APL (Dyalog Classic) , 44 Byte

1∊⍞⍷↑{⍉0,⍵,↑(0,⊢)\↓0,⍵}¨{⍉⌽⍵}\4⍴⊂↑a⊆⍨a≠⊃⌽a←⎕

Probieren Sie es online!

ngn
quelle
Es tut mir leid, aber es scheint, dass Sie hier keine derartigen Eingaben erhalten können, es muss sein \n solche (dh ⎕TC[2]als Trennzeichen haben).
Erik der Outgolfer
@EriktheOutgolfer oh Mist ... Ich werde es später beheben. Vielen Dank.
6.
jetzt behoben, leider viel länger
ngn
0

J , 60 53 Bytes

<@[e.[:,[:(;|.)@>[:<\\.@>[:(<"1,</.)@>@(;|.@|:)[;.2@]

Probieren Sie es online!

Erfordert, dass die erste Eingabe keine Zeilenumbrüche enthält.

Erläuterung:

linkrotate=: ;|.@|:     NB. link with itself rotated 90° ccw
infixes   =: <\\.       NB. list of boxes containing the infixes
lines     =: <"1 , </.  NB. horizontal and diagonal lines, boxed
linkrev   =: ;|.        NB. link with itself reversed
appearin  =: <@[ e. [: , [: linkrev@> [: infixes@> [: lines@>@linkrotate [;.2@]

Probieren Sie es online!

Haken sind nützlich.

user202729
quelle
Es scheint, dass dies auch funktioniert. (51 bytes)
user202729
0

Gelee , 16 Bytes

Eine verwandte (möglicherweise doppelte) Herausforderung gelöst mit 15 dieser 16 Bytes als Kern des Codes ...

ỴZU$3С;ŒD$€Ẏw€Ẹ

Ein dyadischer Link, der eine Liste von Zeichen links und eine Liste von Zeichen rechts akzeptiert, die 1 zurückgibt, wenn sie gefunden werden, und 0, wenn sie nicht gefunden werden.

Probieren Sie es online!

Wie?

ZU$3С;ŒD$€Ẏw€Ẹ - Link: words, grid
   3С          - repeat three times and collect the results (inc input):
  $             -   last two links as a monad:
Z               -     transpose
 U              -     upend     (together these rotate by a quarter)
          €     - for €ach:
         $      -   last two links as a monad:
       ŒD       -     get forward-diagonals
      ;         -     concatenate
           Ẏ    - tighten (to get all the runs across the grid) 
             €  - for €ach run:
            w   -   sublist-index (0 if not found)
              Ẹ - any truthy? (i.e. was the word found?)
Jonathan Allan
quelle