Forum Discussion
A LAMBDA Word Search Puzzle
- 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 ) ));
Thank you for your reply. I spent a couple days on it on and off then dropped it for a few days because I couldn't resolve it with SCAN. I did go through the paces with TOCOL and reducing the letters to a scalar. I didn't feel good about where I was headed. I revisited the task when I thought of how the new Text functions may be helpful by using delimiters, so I played with feeding TEXTSPLIT/TEXTBEFORE/TEXTAFTER a stack of words to delimit on. SergeiBaklan - I need to take some time to study this solution. I've been looking at this puzzle too much lately but will come back to it soon.
The part I couldn't get around with SCAN was achieving something like this (A sample of the first two rows done manually):
The closest I came was getting WAVE and AES (placed in row 2) but the rest that followed was not accurate.
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 )
));