Forum Discussion
Patrick2788
Jul 14, 2022Silver Contributor
A LAMBDA Word Search Puzzle
I've created a 15x10 Word Search. I've included a word list (dynamic range) containing words which might be found in the word search. The goal is to then extract those words when they appear in the...
- Jul 16, 2022
Here is one more variant
//------ variant without TEXTJOIN() reverseColumns= LAMBDA( data, LET( n, COLUMNS( data ), CHOOSECOLS( data, SEQUENCE(n,,n,-1) ) )); reversedText= LAMBDA( str, LET( head, LEFT(str), tail, RIGHT(str, LEN(str) - 1), IF(str = "", "", reversedText(tail) & head) )); isPolindrom= LAMBDA( text, text = reversedText( text ) ); checkSingleWord= LAMBDA( str, vector, LET( getWord, REDUCE("", vector, LAMBDA( a,v, IF( LEFT(str, LEN(a&v)) = a&v, a&v, IF( LEFT(str) = a, v, IF( a = str, a, "" ) ) ) ) ), IF( getWord = str, str, "") )); checkListOfWords= LAMBDA( wordsVector, vector, LET( getWords, REDUCE("", wordsVector, LAMBDA(a,v, VSTACK(a, checkSingleWord( v, vector) ) ) ), IFERROR( FILTER( getWords, getWords <> ""), "" ) )); wordsInMatrix= LAMBDA( data, wordsVector, LET( k, SEQUENCE( ROWS(data) ), scanData, REDUCE(1, k, LAMBDA(a,v, CHOOSECOLS( IF( v < SEQUENCE(,v,v,-1), a, VSTACK(a, checkListOfWords( Words, CHOOSEROWS(data,v) ) ) ), 1 ) )), removeFirst, DROP( scanData, 1 ), FILTER( removeFirst, removeFirst <> "") )); wordsInPuzzle= LAMBDA( data, wordsVector, LET( allWords, SORT( VSTACK( wordsInMatrix( data, wordsVector ), wordsInMatrix( reverseColumns( data ), wordsVector ), wordsInMatrix( TRANSPOSE( data ), wordsVector ), wordsInMatrix( reverseColumns( TRANSPOSE( data ) ), wordsVector ) )), ifPolindroms, MAP(allWords, LAMBDA(v, isPolindrom(v) ) ), polindroms, UNIQUE( FILTER(allWords, ifPolindroms)), notPolindroms, FILTER(allWords, ifPolindroms -1), stack, IF( ISERR(polindroms), notPolindroms, VSTACK( polindroms, notPolindroms ) ), SORT( stack ) ));
PeterBartholomew1
Jul 21, 2022Silver Contributor
Rather than listing the words found, I have identified them on copies of the puzzle.
Worksheet formula
= Solveλ(Puzzle, WordList, 0) +
Solveλ(Puzzle, WordList, 1)
Solveλ = LAMBDA(grid, findlist, d,
LET(
puzzleStr, Grid2Stringλ(grid,d),
extendedList, VSTACK(findlist, MAP(findlist, Reverseλ)),
pointer, MAP(extendedList, LocateWordλ(puzzleStr)),
ptr, FILTER(pointer,pointer),
wLen, FILTER(LEN(extendedList),pointer),
puzzleIdx, SEQUENCE(LEN(puzzleStr)),
n, IF(d, ROWS(grid), COLUMNS(grid)),
String2Gridλ(puzzleIdx,ptr,wLen,n,d)
)
);
Grid2Stringλ = LAMBDA(grid,d,
LET(
nRow, ROWS(grid),
nCol, COLUMNS(grid),
extendedGrid, EXPAND(grid, nRow+1, nCol+1, "|"),
CONCAT(TOCOL(extendedGrid,,d))
)
);
String2Gridλ = LAMBDA(k,wp,wl,n,d,
LET(
s, XLOOKUP(k,wp,wp,0,-1),
ℓ, XLOOKUP(k,wp,wl,0,-1),
b, SIGN(k+1-s <= ℓ),
ext, IF(d,
WRAPCOLS(b,n+1),
WRAPROWS(b,n+1)),
DROP(ext,-1,-1)
)
);
LocateWordλ = LAMBDA(puzzleStr, LAMBDA(word,
IFERROR(FIND(word, puzzleStr),0))
);
Reverseλ = LAMBDA(word,
LET(n, LEN(word), k, SEQUENCE(n, 1, n, -1), CONCAT(MID(word, k, 1)))
);
Something else that occurs to me is that your recursion technique might be the only way forward if the standard across and down wordsearch had words that change direction like a game of 'snake'.
SergeiBaklan
Jul 22, 2022MVP
Nice idea, need to play with it bit more. Do I understood correctly you don't generate "Words found in puzzle" ?
- PeterBartholomew1Jul 22, 2022Silver ContributorTrue. For each word, I record where it occurs (pointer/ptr) and how many characters it occupies (wLen). I do not need to store the word itself, though that would be easier than identifying its location within the grid.