The Sunday New York Times magazine has a new puzzle (June 26, 2022), JUST SAYING by Will Shortz, with the following rules:
- Change one letter in each word to spell a new word. Then arrange the new words to form a familiar proverb or saying. For example, given the words DOES, LIP, LOT, and SWEEPING, you could change them to DOGS, LIE, LET, and SLEEPING and then arrange them to spell "Let sleeping dogs lie."
I'd like code to take input of the form {"alive" ,"mines", "thick", "treat"} and return the puzzle solution ({"great minds think alike"}).
Here is (inefficient) code that returns valid English words that differ by exactly one letter from a given word:
f[myWord_String] :=
Complement[
Flatten@Select[(DictionaryLookup /@ (Flatten@
Table[StringReplacePart[myWord, # , {i, i}] &
/@ CharacterRange["a", "z"],
{i, StringLength[myWord]}])), # != {} &] , {myWord}]
and thus
f["alive"]
(* {"alike", "olive"} *)
Thus f
applied to a target puzzle gives:
wordsets = f /@ {"alive", "mines", "thick", "treat"}
(* {{"alike", "olive"}, {"dines", "fines", "kines", "lines", "manes", "mikes", "miles", "mimes", "minds", "mined", "miner", "minis", "minks", "mints", "minus", "mires", "mites", "mixes", "nines", "pines", "sines", "tines", "vines", "wines", "zines"}, {"chick", "think", "trick"}, {"great", "tread"}} *)
Now I can get a list of all possible scrambled sentences (one word from each word in the original puzzle):
theTuples =Tuples[wordsets]
For each scrambled sentence I can get them in all possible orders (which would include the grammatical, unscrambled, order... if possible):
thePerms = Permutations /@ theTuples
Now I can get all scrambled sentences (though one is not scrambled):
finalCandidates =StringJoin /@ (Riffle[#, " "] & /@ Flatten[thePerms, 1])
Then I hit a problem: How do I automatically select among these to find the sentence that is a familiar proverb or saying?
I've tried some simple grammatical tests, using TextStructure
and "Sentence"
, of this form:
Select[finalCandidates,
StringContainsQ[
TextStructure[#, "ConstituentStrings"], "Sentence"][[1]] &]
but it gives lots and lots of candidate "sentences," most of which are not true grammatical or sensible sentences.
For those interested, here are three (of 24) of the puzzles in this Sunday's Times so you can test your code:
- {"deer", "rue", "stile", "wafers"}
- {"ell","heads","mounds","tile"}
- {"lute","newer","setter","thaw"}
It would be nice to get highly optimized/elegant code (fewest characters), but that isn't necessary.