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 ) ));
Patrick2788 SergeiBaklan PeterBartholomew1 mtarler
I had a go at solving using a lambda I created a while back called ROTATE. It rotates an array by 90 degrees. By stacking the four rotations and joining the text on each row, I think it becomes a case of scanning the "search for" items against the array of rows.
Spent about 10 minutes on this today. I think it works (and quite quickly), but would appreciate your feedback.
Owen
/*
ROTATE
Author: Owen Price
Date: 2022-09-10
Rotates a 2-dimensional array anti-clockwise by 90 degrees.
This is not the same behavior as TRANSPOSE, which reflects an array on the main diagonal
from top-left to bottom-right.
Inputs:
- arr - the input array
- times - the number of times to rotate by 90 degrees
- [iter] - optional - used as a counter by the recursion
Note: iter should not be used when calling this function from a spreadsheet
*/
ROTATE = LAMBDA(arr,times,[iter],
LET(
_times,MOD(times,4),
IF(_times=0,arr,
LET(_iter,IF(ISOMITTED(iter),1,iter),
_cols,COLUMNS(arr),
_rotated,INDEX(arr,SEQUENCE(1,ROWS(arr)),_cols-SEQUENCE(_cols)+1),
IF(_iter=_times,_rotated,ROTATE(_rotated,_times,_iter+1))))));
RotatedStacked = IFERROR(VSTACK(Puzzle,ROTATE(Puzzle,1),ROTATE(Puzzle,2),ROTATE(Puzzle,3)),"");
AsRows = BYROW(RotatedStacked,LAMBDA(r,TEXTJOIN("",TRUE,r)));
fnIsFound = LAMBDA(text, OR(NOT(ISERROR(SEARCH(text,AsRows)))));
Search = REDUCE(,table1[Word List:],LAMBDA(a,b,IF(fnIsFound(b),VSTACK(a,b),a)));
I like the Rotate Lambda. A nifty bit of recursion! I've tested it on square and non-square matrices, and it never fails.
This is my variant:
RotateM(matrix,turns)
=IF(
turns = 0,
matrix,
RotateM(
LET(r, ROWS(TRANSPOSE(matrix)), CHOOSEROWS(TRANSPOSE(matrix), SEQUENCE(r, , r, -1))),
turns - 1
)
)
- flexyourdataAug 03, 2023Iron Contributor
Very neat! I like the way you've used turns-1 to avoid the iter arg. Makes a lot of sense now I see it.
I think I wrote mine before I had a good grasp of CHOOSECOLS. Although I still think it's problematic in some situations where returning single-cell arrays into other functions, what you've done here is really nice.
- mtarlerAug 03, 2023Silver Contributorcan I ask why you have ROWS(TRANSPOSE(matrix)) instead of COLUMNS(matrix) ?
- Patrick2788Aug 03, 2023Silver Contributor
On my first draft of the function, I noticed I wasn't accounting for non-square matrices. The function worked on 1 spin but failed on 2+. I went back and realized the problem was where I pulled R from and how it was a step behind. I used the nesting of ROWS-TRANSPOSE because it's how I anticipated the move in my head, if that makes sense. Recursion is usually not my first go-to and it shows a bit here. I do like how recursive functions can be very concise.