What the code does (not completely obvious by looking at it, I know) is this. It takes the digits of Pi and partitions them into groups of 3. Then it takes each of these groups and turns them into the corresponding integer. Each of these integers is then Mod
'd by 26, (number of letters in the english alphabet) thereby getting values between 0 and 25. This is then used to map to the character codes of the 26 letters using the characteCodesRules
. Then groups of letters wordLength
long are put together and checked to see if they are a word.
But, I see now that my original code has a small bug...
It had
characteCodesRules =
Thread[Range[Length[characteCodes]] -> characteCodes];
but this should have been
characteCodesRules =
Thread[Range[{0, Length[characteCodes] - 1}] -> characteCodes];
So, here is the updated code (so I don't have to edit the whole original post ;-) )
MonkeyPiWords[nLetters_Integer, wordLength_Integer] :=
Module[{characteCodes, characteCodesRules, piDigitsAsCharacterCodes1,
piDigitsAsCharacterCodes2, piDigitsAsCharacterCodes3,
monkeyCharacters1, monkeyWords1, monkeyCharacters2, monkeyWords2,
monkeyCharacters3, monkeyWords3, monkeyWords},
characteCodes = ToCharacterCode["abcdefghijklmnopqrstuvwxyz"];
characteCodesRules =
Thread[Range[0, Length[characteCodes] - 1] -> characteCodes];
piDigitsAsCharacterCodes1 =
Mod[#, 26] & /@
FromDigits /@
Partition[First[RealDigits[N[\[Pi], 3 nLetters]]], 3] /.
characteCodesRules;
piDigitsAsCharacterCodes2 =
Mod[#, 26] & /@
FromDigits /@
Partition[Rest@First[RealDigits[N[\[Pi], 3 nLetters]]], 3] /.
characteCodesRules;
piDigitsAsCharacterCodes3 =
Mod[#, 26] & /@
FromDigits /@
Partition[Rest@Rest@First[RealDigits[N[\[Pi], 3 nLetters]]],
3] /. characteCodesRules;
monkeyCharacters1 = FromCharacterCode /@ piDigitsAsCharacterCodes1;
monkeyWords1 =
StringJoin /@ Partition[monkeyCharacters1, wordLength];
monkeyCharacters2 = FromCharacterCode /@ piDigitsAsCharacterCodes2;
monkeyWords2 =
StringJoin /@ Partition[monkeyCharacters2, wordLength];
monkeyCharacters3 = FromCharacterCode /@ piDigitsAsCharacterCodes3;
monkeyWords3 =
StringJoin /@ Partition[monkeyCharacters3, wordLength];
Union@Flatten[{DictionaryLookup[#, IgnoreCase -> True] & /@
monkeyWords1,
DictionaryLookup[#, IgnoreCase -> True] & /@ monkeyWords2,
DictionaryLookup[#, IgnoreCase -> True] & /@ monkeyWords3}]
]
For 1000 characters this gives (for comparison with your approach's result):
Flatten[{MonkeyPiWords[1000, 1], MonkeyPiWords[1000, 2],
MonkeyPiWords[1000, 3]}]
yielding
{"a", "I", "AD", "ah", "AM", "an", "as", "at", "ax", "BC", "be", \
"bi", "by", "CD", "cs", "cw", "dB", "dc", "DJ", "do", "eh", "em", \
"en", "er", "es", "ET", "ex", "fa", "FM", "GI", "go", "GP", "gs", \
"ha", "hi", "hm", "ho", "HQ", "ID", "in", "IQ", "IT", "jg", "Jo", \
"kc", "KO", "ks", "kW", "la", "Le", "lo", "ls", "ma", "MC", "me", \
"mi", "Mr", "Ms", "mu", "my", "no", "nu", "of", "oh", "OK", "om", \
"on", "or", "ow", "ox", "Oz", "pa", "PC", "pH", "pi", "PM", "re", \
"Rh", "rs", "Rx", "sh", "so", "ta", "ti", "TM", "to", "ts", "TV", \
"Ty", "uh", "UK", "UN", "up", "vs", "Wm", "Wu", "xi", "XL", "ya", \
"ye", "yo", "Ada", "aka", "amp", "bed", "bog", "Coy", "cud", "elk", \
"Ely", "fag", "FAQ", "foe", "Fox", "gee", "git", "GOP", "ins", "IOU", \
"ire", "jam", "Lee", "Lev", "LSD", "Max", "MBA", "MCI", "Moe", "moo", \
"nil", "now", "ode", "ope", "ops", "Orr", "Pei", "pug", "raw", "rev", \
"sad", "sap", "spy", "sty", "tap", "tar", "Tia", "tux", "TVs", "TWA", \
"URL", "way", "woe"}
the same order of magnitude number of words as yours.