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 ) ));
Patrick2788
Jul 19, 2022Silver Contributor
I'm wondering if it's possible (or even sensible) to use recursion with SCAN to check an element in the array to see if it contains a word from the word list when the element LEN is at least 3. The word would be returned and the excess letters would be discarded. I'm messing around with recursion and SUBSTITUTE and receiving memory errors.
Ideally, the SCAN results would be like this:
SergeiBaklan
Jul 19, 2022MVP
Not sure I understood your idea correctly. If we scan only one row (one by one) and expected result is like
when it could be
///--- SCAN row on Words
getWord=
LAMBDA( str, words,
XLOOKUP( str, words, words, 0) );
getWordOnRight=
LAMBDA( str, words,
IFNA( INDEX( Words, XMATCH( TRUE, RIGHT(str, LEN(Words) )= Words ) ), 0 )
);
getReversedWordOnRight=
LAMBDA( str, words,
IFNA( INDEX( Words, XMATCH( TRUE, LEFT( reversedText(str), LEN(Words) )= Words ) ), 0 )
);
scanVector=
LAMBDA( vector, words,
SCAN("", vector, LAMBDA(a,v,
IF( getWord( a, Words ) <> 0, v,
IF( getWordOnRight( a&v, Words ) <> 0,
getWordOnRight( a&v, Words ),
IF( getReversedWordOnRight( a&v, Words ) <> 0,
getReversedWordOnRight( a&v, Words ),
a&v )
)
)
) )
);
I guess could could be more compact, just first iteration.
- Patrick2788Jul 19, 2022Silver ContributorThat's exactly it. My idea involved scanning the entire target array, but it looks like going by row is much better. No need to account for the change in row and less text to discard.
- PeterBartholomew1Jul 20, 2022Silver ContributorI have been trying something different with some success. I reduce the entire puzzle to a single string, padded with "|" between source rows and, rather than reversing the puzzle, I reverse the search words and append them to the original set. The location of the matches within the string is related to the position within the puzzle grid. So far, I have 0 and 1 to show where the matches are, but by combining that with the original grid, I could display the words in their original setting.