# Word Search Puzzle

## Java : 183 211321

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;}


A basic brute force. There's not much else to say, I guess. Input is needle first and haystack second. Assumes grid is newline-terminated.

A slightly more readable version with test case shown:

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;
}
}


## CJam, 46 37 bytes

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


Reads the grid from STDIN and the word as a command-line argument. Prints positive integers for matches and 0 for non-matches.

At the cost of two extra bytes, both strings (word, linefeed, grid) can be read from STDIN:

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


You can try this version online with the CJam interpreter.

### Example run

$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


### Background

Assume the input was the following grid:

ABCD
EFGH
IJKL


Splitting at linefeeds, we obtain the following array:

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


That covers East words (words going from left to right).

Now, we join the elements of A using a string of len(A) linefeeds as separator:

"ABCD⏎⏎⏎EFGH⏎⏎⏎IJKL"


Then, we chop the resulting string in chunks of length len(A) + len(A[0]) + 1:

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


If we "zip" the array (transpose rows and columns), we obtain:

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


That covers South East words.

If we zip A and reverse the order of the result's rows, we obtain:

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


That covers South and – after repeating the process for diagonals – South West words.

Zipping and reversing again, we obtain:

[
"LKJI"
"HGFE"
"DCBA"
]


That covers West and – after repeating the process for diagonals – North West words.

Zipping and reversing once more, we obtain:

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


That covers North and – after repeating the process for diagonals – North East words.

### How it works

The code does as explained in the previous section, with two minor differences:

• It zips and reverses once at the very beginning.
• It computes len(A) + len(A[0]) as len(A + zip(A)).

Finally, it joins all rows of all generated arrays using linefeeds as separators and searches for the word in the resulting string.

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                              ";


## JavaScript (E6) 111 116

Brute force search for every character in every direction - as golfed as I can

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 console

;["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)))


Output

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