Here is the answer to the challenge in the previous post.
First /@
Last[
SortBy[
GatherBy[{#, StringJoin[Sort[ToUpperCase[Characters[#]]]]} &
/@ DictionaryLookup[{"English", All}],
Last],
Length]
]
The idea here is to extract every word from the English dictionary. Then we create pairs consisting of the initial word and the initial word with letters sorted and converted to uppercase. The idea is that the second entry is a anagram key — all words that are anagrams of each other will share the same key.
Then we use GatherBy to consolidate all the pairs with common keys and SortBy to order by the number of anagrams in the set. Finally Last is used to find the words that form the largest anagram set in the English dictionary and First to extract only the words (I drop the keys).
Here is some output that will make the steps clearer.
In[59]:= Take[SortBy[
GatherBy[{#, StringJoin[Sort[ToUpperCase[Characters[#]]]]} & /@
DictionaryLookup[{"English", All}], Last], Length], -10]
Out[59]= {{{“ales”, “AELS”}, {“Elsa”, “AELS”}, {“lase”, “AELS”}, {“leas”,
“AELS”}, {“Lesa”, “AELS”}, {“sale”, “AELS”}, {“seal”, “AELS”}}, {{“capers”,
“ACEPRS”}, {“crapes”, “ACEPRS”}, {“pacers”, “ACEPRS”}, {“parsec”,
“ACEPRS”}, {“recaps”, “ACEPRS”}, {“scrape”, “ACEPRS”}, {“spacer”,
“ACEPRS”}}, {{“carets”, “ACERST”}, {“caster”, “ACERST”}, {“caters”,
“ACERST”}, {“crates”, “ACERST”}, {“reacts”, “ACERST”}, {“recast”,
“ACERST”}, {“traces”, “ACERST”}}, {{“elan”, “AELN”}, {“lane”,
“AELN”}, {“Lane”, “AELN”}, {“lean”, “AELN”}, {“Lean”, “AELN”}, {“Lena”,
“AELN”}, {“Neal”, “AELN”}}, {{“Ingres”, “EGINRS”}, {“reigns”,
“EGINRS”}, {“resign”, “EGINRS”}, {“sering”, “EGINRS”}, {“signer”,
“EGINRS”}, {“singer”, “EGINRS”}, {“Singer”, “EGINRS”}}, {{“notes”,
“ENOST”}, {“onset”, “ENOST”}, {“Seton”, “ENOST”}, {“steno”,
“ENOST”}, {“stone”, “ENOST”}, {“Stone”, “ENOST”}, {“tones”,
“ENOST”}}, {{“opts”, “OPST”}, {“post”, “OPST”}, {“Post”, “OPST”}, {“pots”,
“OPST”}, {“spot”, “OPST”}, {“stop”, “OPST”}, {“tops”, “OPST”}}, {{“pares”,
“AEPRS”}, {“parse”, “AEPRS”}, {“pears”, “AEPRS”}, {“rapes”,
“AEPRS”}, {“reaps”, “AEPRS”}, {“spare”, “AEPRS”}, {“spear”,
“AEPRS”}}, {{“ates”, “AEST”}, {“east”, “AEST”}, {“East”, “AEST”}, {“eats”,
“AEST”}, {“etas”, “AEST”}, {“sate”, “AEST”}, {“seat”, “AEST”}, {“teas”,
“AEST”}}, {{“least”, “AELST”}, {“slate”, “AELST”}, {“Stael”,
“AELST”}, {“stale”, “AELST”}, {“steal”, “AELST”}, {“tales”,
“AELST”}, {“teals”, “AELST”}, {“Tesla”, “AELST”}}}
The above shows the last 10 anagram families with the associated anagram key. The last one is the one used to generate the challenge output.
Elegant solution! (It would be visually neater if the “DictionaryLookup” were on a new line so the whole code example could be viewed at the same time.)
The next-to-last anagram set also had eight elements. But in your sorting and Simon’s, the 5-letter words was deemed longest. What specifically accounts for that?
Thanks for a nice challenge with a neat solution!
Dan
Fixed the formatting. Thanks for pointing that out.
If the Sort is a stable sort then this would be the case because this was the order prior to sorting. In any case the length of the words themselves would not have any bearing on the order because SortBy is only considering the size of each family.
Oh,that’s so cool!I’m a mathematica learner from china,and I’m very impressed by your elegant code!
Would you mind giving me more blogs or websites like yours that play with mathematica?
Thank you!