# The Challenge

Given a list of words and a grid of letters, your job is to determine which of the given words can be found on the grid in all 8 directions (forward, backward, up, down, and the 4 diagonal directions), much like a word search. The grid is toroidal, so the grid wraps around on the edges. Letters can be reused with this wrap-around property.

Wrapping around for diagonals behaves as you might expect. On a 4x6 grid going diagonally down and right, you would expect movement to look like this:

9 . 5 . 1 .
. . . 6 . 2
3 . . . 7 .
. 4 . . . 8


For an example of a wrap-around reuse word:

S E A H O R


Would be able to make SEAHORSE

# Example Test Cases

Given this grid and the word list [ANT, COW, PIG]:

A N T
W C O
P G I


The result would be [ANT, COW, PIG]

Given this grid and the word list [CAT, DOG, DUCK, GOOSE, PUMPKIN]:

N O O D M E
O I O C U U
P G K O T C
K A U P S K


The result would be [DOG, DUCK, PUMPKIN]

Given this grid and the word list [TACO, BEEF, PORK]:

T A C B
A P O R
K E E F
B F C P


The result would be an empty list

Given this grid and the word list [ACHE, ASK, BAD, BOOK, COOK, CROW, GAS, GOOD, LESS, MARK, MASK, MEAL, SAME, SEAHORSE, SELL, SHOW, SLACK, WOOD]:

G S L A C K
H A E S R O
C M S K O O
A K S D W B


The result would be [ASK, BOOK, COOK, CROW, GAS, GOOD, LESS, MASK, SEAHORSE, SHOW, SLACK]

Given this grid and a list of all English words that are at least 3 letters long:

A R T U P
N T U B O
E S R O H
Q E T I U
E A T D P


The result would be [AEQ, AES, ANE, ART, ARTS, ATRIP, BOID, BON, BREE, BUD, BUT, DUB, DUE, DUET, EAN, EAR, EAT, EER, EST, HES, HIT, HOP, HOR, HORS, HORSE, HUP, NAE, NOB, NOBUT, ONT, OOT, OPP, ORS, OUR, OUT, PAR, PART, PAT, PEA, PEAT, PEE, PEER, PIR, POH, PUT, QAT, QUI, QUIT, QUITE, RAP, REE, RIP, RIPA, RTI, RUT, SEA, SEAR, STD, STR, STRA, STRAE, SUU, TAA, TAE, TAP, TAPIR, TEE, TIU, TOO, TRA, TRAP, TRI, TRIP, TUB, TUP, TUR, UDI, UIT, URE, UTE]

# Rules

• No exploiting standard loopholes
• This is , so shortest code wins
• Input and output may be in any convenient format
• You may assume that both the grid and the words list will use only capital letters
• The output order of the words does not matter
• You do not have to, but may, filter out duplicates
• – Oliver May 5 '18 at 5:20
• @Lynn Even though I can think of one other approach, I agree, it too reduces to WSP. – Erik the Outgolfer May 5 '18 at 14:10
• Where were all of you when this was in the sandbox? Just saying. It got 3 upvotes there. – Beefster May 8 '18 at 22:25
• This is clearly not a duplicate. Although being on a torus doesn't sound like much of a change, most implementations will be significantly different. Here's my Python 3 approach anyway lambda s,d:[w for w in d if any(r(s,w,x,y,i,j)for x in range(l(s[0]))for y in range(l(s))for i in[-1,0,1]for j in[-1,0,1]if i*i+j*j)];r=lambda s,w,x,y,i,j:w==""or s[y%l(s)][x%l(s[0])]==w[0]and r(s,w[1:],x+i,y+j,i,j);l=len – Matthew Jensen Dec 17 '19 at 23:01

# Jelly, 25 bytes

Lẋ@Zɗ⁺ZU$3Ð¡;ŒD$€Ẏw€⁸ẸðÐf


A dyadic link accepting a list of lists of characters (the words) on the left and a list of lists of characters (the rows of the grid) on the right which returns a list of list of characters (the found words).

Try it online!

### How?

Filters the words by their existence in the grid tiled to be word-length times as wide and word-length times as high:

Lẋ@Zɗ⁺ZU$3Ð¡;ŒD$€Ẏw€⁸ẸðÐf - Link: words, grid
Ðf - filter (the words) keeping those for which
⁺                    -   perform this twice:
L                         -       length (of the current word)
ẋ@                       -       repeat (the rows) by (that number)
Z                      -       transpose (making the rows become the columns)
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)
⁸     -   chain's left argument (the word)
€      -   for €ach run:
Ẹ    -   any truthy? (i.e. was the word found?)


## Clojure, 203 180 bytes

#(let[C count R range h(C %)w(C(% 0))](for[Q %2[y x][[1 0][0 1][-1 0][0 -1][1 1][1 -1][-1 -1][-1 1]]r(R h)c(R w):when(=(for[i(R(C Q))]((%(mod(+(* y i)r)h))(mod(+(* x i)c)w)))Q)]Q))


The grid must be a vector of vector of characters and the word list must be a sequence of sequence of characters. Sorry, no strings ;)

# JavaScript (Node.js), 269214164 163 bytes

-50 bytes with the golfing I learned since last year.
-1 byte thanks to Redwolf Programs

l=>g=>l.filter(w=>g.some((r,y)=>r.some((c,x,r,z=[-1,0,1],m=(a,b,c=b.length)=>(a%c+c)%c)=>z.some(l=>z.some(p=>[...w].every((h,i)=>h==g[m(l*i+y,g)][m(p*i+x,r)]))))))


Try it online!

old 214 bytes version:

(l,g)=>l.filter(w=>g.some((r,y)=>r.some((c,x,r,e=w.split,m=(a,b)=>((a%b)+b)%b)=>[[0,1],[0,-1],[1,0],[-1,0],[1,1],[1,-1],[-1,1],[-1,-1]].some(v=>e.every((h,i)=>h==g[m(v[0]*i+y,g.length)][m(v[1]*i+x,r.length)])))))


Try it online!

(l, g) =>
l.filter(w =>
g.some((r, y) => //loop through rows
r.some((c, x, r, e = w.split, //loop through columns and split word in chars
m = (a, b) => ((a % b) + b) % b) //modulo function which also works for negative
=>
[[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]].some(v => //the different directions
e.every((h, i)
=> h == g[m(v[0] * i + y, g.length)][m(v[1] * i + x, r.length)]
)
)
)
)
)

• -1 byte: replace (l,g)=> with l=>g=>, and input is taken as (l)(g) – Redwolf Programs Dec 17 '19 at 21:11
• @RedwolfPrograms Thanks, I changed it. Not sure how to cut off more bytes – Joost K Dec 18 '19 at 8:20