I'm ignoring the conversion to a number because that's trivial once you have a valid phrase in place.
Here's a prefix trie approach to getting words. It won't be fast since DictionaryLookup
is slow, but I think this is about as good as you can do if you're trying to get an exhaustive list.
First we get all the classes of prefixes, and define some stuff to build a trie
classes = ToLowerCase@EntityValue[EntityClass["Element", All], "Abbreviation"];
validPatternQ[p_] :=
Length[DictionaryLookup[p, 1, IgnoreCase -> True]] > 0;
validStartQ[p_] :=
validPatternQ[p <> "*"];
validStartQ[p_, q_] :=
validStartQ[p <> q];
$defaultTrieDepth = 1;
ClearAll[fillTrie];
fillTrie[pref_, classes_, test_, depth : _Integer : $defaultTrieDepth] :=
Block[{curTrie = <||>, t},
Do[
If[test[pref, k],
If[depth > 0,
t = fillTrie[pref <> k, classes, test, depth - 1];
curTrie[k] = If[Length[t] == 0, pref <> k, t],
curTrie[k] = pref <> k
]
],
{k, classes}
];
curTrie
]
This bottoms out at some depth (I set that to 1
out of laziness) and just checks if attaching the next prefix on the previous one has matches any valid word patterns. I'm guessing internally DictionaryLookup
is using a similar kind of trie.
Now we can start from the empty string and start building (I elided some of the output)
wat = fillTrie["", classes, validStartQ, 1]
<|"h" -> <|"b" -> "hb", "o" -> "ho", "al" -> "hal", "ar" -> "har",
"as" -> "has", "y" -> "hy", "mo" -> "hmo", "ag" -> "hag", "in" -> "hin",
"i" -> "hi", "eu" -> "heu", "er" -> "her", "tm" -> "htm", "yb" -> "hyb",
"os" -> "hos", "ir" -> "hir", "au" -> "hau", "at" -> "hat", "ac" -> "hac",
"u" -> "hu", "am" -> "ham", "es" -> "hes", "og" -> "hog"|>,
"he" -> <|"li" -> "heli", "be" -> "hebe", "b" -> "heb", "c" -> "hec",
"n" -> "hen", "f" -> "hef", "al" -> "heal", "si" -> "hesi", "p" -> "hep",
"s" -> "hes", "ar" -> "hear", "ca" -> "heca", "cu" -> "hecu", "ge" -> "hege",
"br" -> "hebr", "rb" -> "herb", "y" -> "hey", "mo" -> "hemo",
"in" -> "hein", "te" -> "hete", "i" -> "hei", "xe" -> "hexe", "nd" -> "hend",
"w" -> "hew", "re" -> "here", "ir" -> "heir", "pt" -> "hept",
"pb" -> "hepb", "at" -> "heat", "rn" -> "hern", "ra" -> "hera",
"pa" -> "hepa", "u" -> "heu", "np" -> "henp", "lv" -> "helv"|>,
"li" -> <|"li" -> "lili", "be" -> "libe", "b" -> "lib", "c" -> "lic",
"n" -> "lin", "o" -> "lio", "f" -> "lif", "ne" -> "line", "na" -> "lina",
"p" -> "lip", "s" -> "lis", "ar" -> "liar", "k" -> "lik", "ti" -> "liti",
"v" -> "liv", "mn" -> "limn", "fe" -> "life", "co" -> "lico", "ni" -> "lini",
"ga" -> "liga", "br" -> "libr", "mo" -> "limo", "tc" -> "litc",
"sb" -> "lisb", "te" -> "lite", "ba" -> "liba", "la" -> "lila",
"ce" -> "lice", "pr" -> "lipr", "nd" -> "lind", "eu" -> "lieu",
"tm" -> "litm", "ta" -> "lita", "re" -> "lire", "pt" -> "lipt",
"bi" -> "libi", "po" -> "lipo", "ra" -> "lira", "th" -> "lith",
"pa" -> "lipa", "es" -> "lies", "no" -> "lino", "ds" -> "lids"|>,
"be" -> <|"h" -> "beh", "he" -> "behe", "li" -> "beli", "b" -> "beb",
"c" -> "bec", "n" -> "ben", "o" -> "beo", "f" -> "bef", "ne" -> "bene",
"na" -> "bena", "si" -> "besi", "s" -> "bes", "cl" -> "becl", "ar" -> "bear",
"k" -> "bek", "ca" -> "beca", "ti" -> "beti", "v" -> "bev", "fe" -> "befe",
"co" -> "beco", "ni" -> "beni", "ga" -> "bega", "ge" -> "bege",
"as" -> "beas", "se" -> "bese", "rb" -> "berb", "y" -> "bey", "mo" -> "bemo",
"tc" -> "betc", "ag" -> "beag", "in" -> "bein", "te" -> "bete",
"i" -> "bei", "la" -> "bela", "nd" -> "bend", "sm" -> "besm", "ho" -> "beho",
"er" -> "beer", "lu" -> "belu", "ta" -> "beta", "w" -> "bew",
"re" -> "bere", "ir" -> "beir", "au" -> "beau", "at" -> "beat",
"rn" -> "bern", "fr" -> "befr", "ra" -> "bera", "ac" -> "beac",
"th" -> "beth", "u" -> "beu", "am" -> "beam", "es" -> "bees", "db" -> "bedb",
"ds" -> "beds", "rg" -> "berg", "ts" -> "bets"|>,
"b" -> <|"h" -> "bh", "li" -> "bli", "b" -> "bb", "c" -> "bc", "o" -> "bo",
"al" -> "bal", "ar" -> "bar", "as" -> "bas", "y" -> "by", "ru" -> "bru",
"ag" -> "bag", "in" -> "bin", "i" -> "bi", "la" -> "bla", "eu" -> "beu",
"ho" -> "bho", "er" -> "ber", "yb" -> "byb", "lu" -> "blu", "re" -> "bre",
"os" -> "bos", "ir" -> "bir", "au" -> "bau", "at" -> "bat", "rn" -> "brn",
"ra" -> "bra", "ac" -> "bac", "u" -> "bu", "am" -> "bam", "es" -> "bes",
"og" -> "bog"|>,
"c" -> <|"h" -> "ch", "he" -> "che", "li" -> "cli", "b" -> "cb", "n" -> "cn",
"o" -> "co", "f" -> "cf", "al" -> "cal", "p" -> "cp", "s" -> "cs",
"ar" -> "car", "ni" -> "cni", "as" -> "cas", "y" -> "cy", "ru" -> "cru",
"ag" -> "cag", "in" -> "cin", "te" -> "cte", "i" -> "ci", "la" -> "cla",
"ho" -> "cho", "er" -> "cer", "yb" -> "cyb", "lu" -> "clu", "w" -> "cw",
"re" -> "cre", "os" -> "cos", "ir" -> "cir", "au" -> "cau", "at" -> "cat",
"ra" -> "cra", "ac" -> "cac", "u" -> "cu", "pu" -> "cpu", "am" -> "cam",
"es" -> "ces", "og" -> "cog"|>,
"n" -> <|"h" -> "nh", "b" -> "nb", "c" -> "nc", "o" -> "no", "f" -> "nf",
"ar" -> "nar", "k" -> "nk", "ca" -> "nca", "co" -> "nco", "ga" -> "nga",
"as" -> "nas", "kr" -> "nkr", "y" -> "ny", "ag" -> "nag", "in" -> "nin",
"i" -> "ni", "ba" -> "nba", "eu" -> "neu", "er" -> "ner", "os" -> "nos",
"ir" -> "nir", "au" -> "nau", "at" -> "nat", "ac" -> "nac", "th" -> "nth",
"u" -> "nu", "am" -> "nam", "es" -> "nes", "fl" -> "nfl", "og" -> "nog"|>,
"o" -> <|"h" -> "oh", "li" -> "oli", "be" -> "obe", "b" -> "ob", "c" -> "oc",
"n" -> "on", "o" -> "oo", "f" -> "of", "ne" -> "one", "na" -> "ona",
"si" -> "osi", "p" -> "op", "s" -> "os", "ar" -> "oar", "k" -> "ok",
"ca" -> "oca", "sc" -> "osc", "ti" -> "oti", "v" -> "ov", "mn" -> "omn",
"fe" -> "ofe", "ni" -> "oni", "cu" -> "ocu", "as" -> "oas", "kr" -> "okr",
"rb" -> "orb", "y" -> "oy", "in" -> "oin", "sb" -> "osb", "i" -> "oi",
"xe" -> "oxe", "ba" -> "oba", "la" -> "ola", "ce" -> "oce", "pr" -> "opr",
"sm" -> "osm", "eu" -> "oeu", "gd" -> "ogd", "dy" -> "ody", "ho" -> "oho",
"er" -> "oer", "w" -> "ow", "re" -> "ore", "pt" -> "opt", "bi" -> "obi",
"po" -> "opo", "at" -> "oat", "rn" -> "orn", "ra" -> "ora", "th" -> "oth",
"pa" -> "opa", "u" -> "ou", "pu" -> "opu", "es" -> "oes", "md" -> "omd",
"no" -> "ono", "sg" -> "osg", "hs" -> "ohs", "rg" -> "org"|>,
"f" -> <|"li" -> "fli", "b" -> "fb", "n" -> "fn", "o" -> "fo", "al" -> "fal",
"ar" -> "far", "as" -> "fas", "ru" -> "fru", "ag" -> "fag", "in" -> "fin",
"i" -> "fi", "la" -> "fla", "eu" -> "feu", "er" -> "fer", "lu" -> "flu",
"re" -> "fre", "os" -> "fos", "ir" -> "fir", "au" -> "fau", "bi" -> "fbi",
"at" -> "fat", "ra" -> "fra", "ac" -> "fac", "u" -> "fu", "am" -> "fam",
"es" -> "fes", "og" -> "fog"|>,
"ne" -> <|"h" -> "neh", "he" -> "nehe", "b" -> "neb", "c" -> "nec",
"o" -> "neo", "f" -> "nef", "al" -> "neal", "p" -> "nep", "s" -> "nes",
"ar" -> "near", "v" -> "nev", "cr" -> "necr", "fe" -> "nefe", "ga" -> "nega",
"ge" -> "nege", "br" -> "nebr", "ru" -> "neru", "i" -> "nei",
"ce" -> "nece", "tb" -> "netb", "w" -> "new", "re" -> "nere", "pt" -> "nept",
"po" -> "nepo", "at" -> "neat", "th" -> "neth", "pa" -> "nepa",
"u" -> "neu", "rf" -> "nerf", "ts" -> "nets", "og" -> "neog"|>,
"na" -> <|"h" -> "nah", "b" -> "nab", "c" -> "nac", "n" -> "nan", "o" -> "nao",
"f" -> "naf", "ne" -> "nane", "na" -> "nana", "p" -> "nap", "s" -> "nas",
"k" -> "nak", "sc" -> "nasc", "ti" -> "nati", "v" -> "nav", "cr" -> "nacr",
"ga" -> "naga", "y" -> "nay", "tc" -> "natc", "te" -> "nate", "i" -> "nai",
"ce" -> "nace", "ta" -> "nata", "ir" -> "nair", "bi" -> "nabi",
"po" -> "napo", "rn" -> "narn", "ra" -> "nara", "ac" -> "naac",
"th" -> "nath", "pa" -> "napa", "u" -> "nau", "no" -> "nano"|>, "mg" -> <||>,
"al" -> <|"h" -> "alh", "he" -> "alhe", "li" -> "alli", "be" -> "albe",
"b" -> "alb", "c" -> "alc", "n" -> "aln", "o" -> "alo", "f" -> "alf",
"p" -> "alp", "s" -> "als", "ar" -> "alar", "k" -> "alk", "ca" -> "alca",
"ti" -> "alti", "v" -> "alv", "co" -> "alco", "ni" -> "alni", "cu" -> "alcu",
"ga" -> "alga", "ge" -> "alge", "as" -> "alas", "y" -> "aly",
"mo" -> "almo", "in" -> "alin", "te" -> "alte", "i" -> "ali", "ba" -> "alba",
"la" -> "alla", "ce" -> "alce", "eu" -> "aleu", "er" -> "aler",
"tm" -> "altm", "lu" -> "allu", "ta" -> "alta", "w" -> "alw", "re" -> "alre",
"bi" -> "albi", "po" -> "alpo", "fr" -> "alfr", "ac" -> "alac",
"th" -> "alth", "pa" -> "alpa", "u" -> "alu", "am" -> "alam", "cm" -> "alcm",
"es" -> "ales", "ts" -> "alts"|>,
"si" -> <|"h" -> "sih", "li" -> "sili", "be" -> "sibe", "b" -> "sib",
"c" -> "sic", "n" -> "sin", "o" -> "sio", "f" -> "sif", "ne" -> "sine",
"na" -> "sina", "p" -> "sip", "s" -> "sis", "k" -> "sik", "ti" -> "siti",
"v" -> "siv", "ni" -> "sini", "se" -> "sise", "mo" -> "simo", "tc" -> "sitc",
"te" -> "site", "xe" -> "sixe", "cs" -> "sics", "la" -> "sila",
"nd" -> "sind", "er" -> "sier", "lu" -> "silu", "ta" -> "sita",
"re" -> "sire", "bi" -> "sibi", "am" -> "siam", "es" -> "sies",
"no" -> "sino", "nh" -> "sinh", "lv" -> "silv", "ts" -> "sits"|>,
"p" -> <|"h" -> "ph", "he" -> "phe", "li" -> "pli", "c" -> "pc", "n" -> "pn",
"o" -> "po", "f" -> "pf", "ne" -> "pne", "al" -> "pal", "si" -> "psi",
"p" -> "pp", "s" -> "ps", "ar" -> "par", "fe" -> "pfe", "as" -> "pas",
"se" -> "pse", "y" -> "py", "ru" -> "pru", "ag" -> "pag", "in" -> "pin",
"te" -> "pte", "i" -> "pi", "cs" -> "pcs", "la" -> "pla", "pm" -> "ppm",
"eu" -> "peu", "ho" -> "pho", "er" -> "per", "lu" -> "plu", "ta" -> "pta",
"re" -> "pre", "os" -> "pos", "ir" -> "pir", "au" -> "pau", "at" -> "pat",
"ra" -> "pra", "ac" -> "pac", "u" -> "pu", "am" -> "pam", "es" -> "pes",
"og" -> "pog"|>,
"s" -> <|"h" -> "sh", "he" -> "she", "li" -> "sli", "c" -> "sc", "n" -> "sn",
"o" -> "so", "ne" -> "sne", "na" -> "sna", "al" -> "sal", "p" -> "sp",
"s" -> "ss", "cl" -> "scl", "ar" -> "sar", "k" -> "sk", "ca" -> "sca",
"ti" -> "sti", "v" -> "sv", "cr" -> "scr", "co" -> "sco", "ni" -> "sni",
"cu" -> "scu", "as" -> "sas", "y" -> "sy", "mo" -> "smo", "ag" -> "sag",
"in" -> "sin", "te" -> "ste", "i" -> "si", "la" -> "sla", "ce" -> "sce",
"pr" -> "spr", "eu" -> "seu", "ho" -> "sho", "er" -> "ser", "yb" -> "syb",
"lu" -> "slu", "ta" -> "sta", "w" -> "sw", "os" -> "sos", "ir" -> "sir",
"au" -> "sau", "po" -> "spo", "at" -> "sat", "ac" -> "sac", "pa" -> "spa",
"u" -> "su", "pu" -> "spu", "am" -> "sam", "es" -> "ses", "no" -> "sno",
"og" -> "sog"|>,
"cl" -> <|"o" -> "clo", "ar" -> "clar", "as" -> "clas", "y" -> "cly",
"in" -> "clin", "i" -> "cli", "er" -> "cler", "os" -> "clos", "au" -> "clau",
"at" -> "clat", "ac" -> "clac", "u" -> "clu", "am" -> "clam",
"og" -> "clog"|>,
"ar" -> <|"li" -> "arli", "b" -> "arb", "c" -> "arc", "n" -> "arn",
"o" -> "aro", "ne" -> "arne", "al" -> "aral", "si" -> "arsi", "p" -> "arp",
"s" -> "ars", "ar" -> "arar", "k" -> "ark", "ca" -> "arca", "ti" -> "arti",
"ge" -> "arge", "se" -> "arse", "y" -> "ary", "mo" -> "armo", "rh" -> "arrh",
"ag" -> "arag", "te" -> "arte", "i" -> "ari", "cs" -> "arcs",
"ce" -> "arce", "ta" -> "arta", "re" -> "arre", "os" -> "aros",
"au" -> "arau", "tl" -> "artl", "bi" -> "arbi", "ra" -> "arra",
"ac" -> "arac", "th" -> "arth", "u" -> "aru", "am" -> "aram", "es" -> "ares",
"no" -> "arno", "nh" -> "arnh", "mc" -> "armc", "ts" -> "arts"|>,
"k" -> <|"h" -> "kh", "li" -> "kli", "c" -> "kc", "n" -> "kn", "o" -> "ko",
"ne" -> "kne", "na" -> "kna", "al" -> "kal", "p" -> "kp", "s" -> "ks",
"ar" -> "kar", "v" -> "kv", "ni" -> "kni", "as" -> "kas", "y" -> "ky",
"ru" -> "kru", "ag" -> "kag", "in" -> "kin", "i" -> "ki", "la" -> "kla",
"ho" -> "kho", "er" -> "ker", "lu" -> "klu", "w" -> "kw", "re" -> "kre",
"os" -> "kos", "ir" -> "kir", "au" -> "kau", "at" -> "kat", "ra" -> "kra",
"u" -> "ku", "am" -> "kam", "es" -> "kes", "no" -> "kno"|>,
"ca" -> <|"h" -> "cah", "li" -> "cali", "be" -> "cabe", "b" -> "cab",
"c" -> "cac", "n" -> "can", "f" -> "caf", "ne" -> "cane", "na" -> "cana",
"si" -> "casi", "p" -> "cap", "s" -> "cas", "k" -> "cak", "ca" -> "caca",
"sc" -> "casc", "ti" -> "cati", "v" -> "cav", "fe" -> "cafe", "co" -> "caco",
"ni" -> "cani", "ge" -> "cage", "se" -> "case", "br" -> "cabr",
"rb" -> "carb", "y" -> "cay", "nb" -> "canb", "mo" -> "camo", "tc" -> "catc",
"ru" -> "caru", "rh" -> "carh", "in" -> "cain", "te" -> "cate",
"i" -> "cai", "ba" -> "caba", "la" -> "cala", "pr" -> "capr", "nd" -> "cand",
"tb" -> "catb", "ho" -> "caho", "er" -> "caer", "lu" -> "calu",
"ta" -> "cata", "w" -> "caw", "re" -> "care", "ir" -> "cair", "pt" -> "capt",
"tl" -> "catl", "bi" -> "cabi", "po" -> "capo", "rn" -> "carn",
"ra" -> "cara", "th" -> "cath", "pa" -> "capa", "u" -> "cau", "pu" -> "capu",
"es" -> "caes", "md" -> "camd", "no" -> "cano", "rf" -> "carf",
"ds" -> "cads", "rg" -> "carg", "mc" -> "camc", "lv" -> "calv",
"ts" -> "cats"|>,
"sc" -> <|"h" -> "sch", "he" -> "sche", "o" -> "sco", "al" -> "scal",
"ar" -> "scar", "y" -> "scy", "ru" -> "scru", "in" -> "scin", "i" -> "sci",
"ho" -> "scho", "re" -> "scre", "at" -> "scat", "ra" -> "scra", "u" -> "scu",
"am" -> "scam"|>,
"ti" -> <|"li" -> "tili", "be" -> "tibe", "b" -> "tib", "c" -> "tic",
"n" -> "tin", "f" -> "tif", "ne" -> "tine", "na" -> "tina", "p" -> "tip",
"s" -> "tis", "ar" -> "tiar", "ti" -> "titi", "co" -> "tico", "ni" -> "tini",
"ge" -> "tige", "mo" -> "timo", "tc" -> "titc", "te" -> "tite",
"cs" -> "tics", "nd" -> "tind", "dy" -> "tidy", "er" -> "tier",
"tm" -> "titm", "ta" -> "tita", "re" -> "tire", "pt" -> "tipt",
"tl" -> "titl", "bi" -> "tibi", "ra" -> "tira", "th" -> "tith",
"np" -> "tinp", "es" -> "ties", "db" -> "tidb"|>,
"v" -> <|"h" -> "vh", "c" -> "vc", "o" -> "vo", "al" -> "val", "s" -> "vs",
"ar" -> "var", "cr" -> "vcr", "as" -> "vas", "y" -> "vy", "ag" -> "vag",
"in" -> "vin", "i" -> "vi", "la" -> "vla", "er" -> "ver", "hf" -> "vhf",
"ir" -> "vir", "au" -> "vau", "at" -> "vat", "ac" -> "vac", "u" -> "vu",
"am" -> "vam", "es" -> "ves", "hs" -> "vhs", "og" -> "vog"|>,
"cr" -> <|"o" -> "cro", "as" -> "cras", "y" -> "cry", "ag" -> "crag",
"in" -> "crin", "i" -> "cri", "yb" -> "cryb", "os" -> "cros", "at" -> "crat",
"ac" -> "crac", "u" -> "cru", "am" -> "cram", "es" -> "cres"|>,
"mn" -> <||>,
"fe" -> <|"li" -> "feli", "b" -> "feb", "c" -> "fec", "n" -> "fen",
"ne" -> "fene", "al" -> "feal", "s" -> "fes", "ar" -> "fear", "ca" -> "feca",
"ti" -> "feti", "v" -> "fev", "ni" -> "feni", "cu" -> "fecu",
"as" -> "feas", "br" -> "febr", "rb" -> "ferb", "y" -> "fey", "mo" -> "femo",
"tc" -> "fetc", "ru" -> "feru", "in" -> "fein", "te" -> "fete",
"i" -> "fei", "ce" -> "fece", "nd" -> "fend", "ta" -> "feta", "w" -> "few",
"tl" -> "fetl", "at" -> "feat", "rn" -> "fern", "ra" -> "fera", "u" -> "feu",
"es" -> "fees", "ds" -> "feds", "rg" -> "ferg"|>,
"co" -> <|"h" -> "coh", "he" -> "cohe", "li" -> "coli", "b" -> "cob",
"c" -> "coc", "n" -> "con", "o" -> "coo", "f" -> "cof", "ne" -> "cone",
"na" -> "cona", "al" -> "coal", "si" -> "cosi", "p" -> "cop", "s" -> "cos",
"ar" -> "coar", "k" -> "cok", "ca" -> "coca", "ti" -> "coti", "v" -> "cov",
"co" -> "coco", "ni" -> "coni", "ge" -> "coge", "as" -> "coas",
"se" -> "cose", "br" -> "cobr", "rb" -> "corb", "y" -> "coy", "mo" -> "como",
"ru" -> "coru", "ag" -> "coag", "in" -> "coin", "sb" -> "cosb",
"te" -> "cote", "i" -> "coi", "xe" -> "coxe", "ba" -> "coba", "la" -> "cola",
"pr" -> "copr", "nd" -> "cond", "sm" -> "cosm", "dy" -> "cody",
"ho" -> "coho", "er" -> "coer", "lu" -> "colu", "ta" -> "cota", "w" -> "cow",
"re" -> "core", "os" -> "coos", "ir" -> "coir", "pt" -> "copt",
"au" -> "coau", "at" -> "coat", "rn" -> "corn", "ra" -> "cora",
"ac" -> "coac", "pa" -> "copa", "u" -> "cou", "pu" -> "copu", "rf" -> "corf",
"mt" -> "comt", "ds" -> "cods", "rg" -> "corg", "ts" -> "cots"|>,
"ni" -> <|"h" -> "nih", "be" -> "nibe", "b" -> "nib", "c" -> "nic",
"n" -> "nin", "o" -> "nio", "f" -> "nif", "ne" -> "nine", "na" -> "nina",
"p" -> "nip", "s" -> "nis", "k" -> "nik", "ca" -> "nica", "co" -> "nico",
"ge" -> "nige", "se" -> "nise", "ag" -> "niag", "te" -> "nite",
"xe" -> "nixe", "ce" -> "nice", "ta" -> "nita", "re" -> "nire",
"ac" -> "niac", "am" -> "niam", "ts" -> "nits"|>,
"cu" -> <|"li" -> "culi", "be" -> "cube", "b" -> "cub", "c" -> "cuc",
"n" -> "cun", "f" -> "cuf", "ne" -> "cune", "na" -> "cuna", "p" -> "cup",
"s" -> "cus", "ti" -> "cuti", "v" -> "cuv", "cu" -> "cucu", "rb" -> "curb",
"in" -> "cuin", "te" -> "cute", "i" -> "cui", "ba" -> "cuba", "pr" -> "cupr",
"tb" -> "cutb", "ta" -> "cuta", "re" -> "cure", "tl" -> "cutl",
"pb" -> "cupb", "bi" -> "cubi", "po" -> "cupo", "ra" -> "cura",
"es" -> "cues", "rf" -> "curf", "ds" -> "cuds", "lv" -> "culv",
"ts" -> "cuts"|>,
"ga" -> <|"li" -> "gali", "b" -> "gab", "c" -> "gac", "n" -> "gan",
"o" -> "gao", "f" -> "gaf", "ne" -> "gane", "p" -> "gap", "s" -> "gas",
"sc" -> "gasc", "ti" -> "gati", "v" -> "gav", "cr" -> "gacr", "ga" -> "gaga",
"ge" -> "gage", "se" -> "gase", "br" -> "gabr", "rb" -> "garb",
"y" -> "gay", "mo" -> "gamo", "in" -> "gain", "sb" -> "gasb", "te" -> "gate",
"i" -> "gai", "ba" -> "gaba", "la" -> "gala", "nd" -> "gand",
"sm" -> "gasm", "lu" -> "galu", "w" -> "gaw", "re" -> "gare", "tl" -> "gatl",
"rn" -> "garn", "ra" -> "gara", "th" -> "gath", "u" -> "gau",
"rf" -> "garf", "ds" -> "gads", "rg" -> "garg", "lv" -> "galv",
"ts" -> "gats"|>,
"ge" -> <|"h" -> "geh", "he" -> "gehe", "li" -> "geli", "c" -> "gec",
"n" -> "gen", "o" -> "geo", "f" -> "gef", "ne" -> "gene", "na" -> "gena",
"s" -> "ges", "ar" -> "gear", "ni" -> "geni", "rb" -> "gerb", "y" -> "gey",
"mo" -> "gemo", "ru" -> "geru", "i" -> "gei", "la" -> "gela", "nd" -> "gend",
"ta" -> "geta", "w" -> "gew", "os" -> "geos", "ra" -> "gera",
"th" -> "geth", "es" -> "gees", "no" -> "geno", "ts" -> "gets",
"og" -> "geog"|>,
"as" -> <|"h" -> "ash", "he" -> "ashe", "be" -> "asbe", "b" -> "asb",
"c" -> "asc", "o" -> "aso", "si" -> "assi", "p" -> "asp", "s" -> "ass",
"k" -> "ask", "ti" -> "asti", "cr" -> "ascr", "co" -> "asco", "ga" -> "asga",
"se" -> "asse", "y" -> "asy", "in" -> "asin", "te" -> "aste", "i" -> "asi",
"la" -> "asla", "ce" -> "asce", "ho" -> "asho", "hf" -> "ashf",
"ta" -> "asta", "w" -> "asw", "hg" -> "ashg", "th" -> "asth", "pa" -> "aspa",
"u" -> "asu", "am" -> "asam"|>,
"se" -> <|"li" -> "seli", "b" -> "seb", "c" -> "sec", "n" -> "sen",
"o" -> "seo", "ne" -> "sene", "na" -> "sena", "al" -> "seal", "p" -> "sep",
"s" -> "ses", "cl" -> "secl", "ar" -> "sear", "ca" -> "seca", "v" -> "sev",
"cr" -> "secr", "co" -> "seco", "ni" -> "seni", "cu" -> "secu",
"ga" -> "sega", "as" -> "seas", "rb" -> "serb", "y" -> "sey", "mo" -> "semo",
"ru" -> "seru", "ag" -> "seag", "in" -> "sein", "i" -> "sei",
"xe" -> "sexe", "cs" -> "secs", "ba" -> "seba", "la" -> "sela",
"ce" -> "sece", "nd" -> "send", "tb" -> "setb", "er" -> "seer", "w" -> "sew",
"re" -> "sere", "pt" -> "sept", "po" -> "sepo", "at" -> "seat",
"ra" -> "sera", "ac" -> "seac", "th" -> "seth", "pa" -> "sepa", "u" -> "seu",
"pu" -> "sepu", "am" -> "seam", "es" -> "sees", "no" -> "seno",
"rf" -> "serf", "mt" -> "semt", "rg" -> "serg", "lv" -> "selv",
"ts" -> "sets"|>,
"br" -> <|"n" -> "brn", "o" -> "bro", "as" -> "bras", "y" -> "bry",
"ag" -> "brag", "in" -> "brin", "i" -> "bri", "os" -> "bros", "at" -> "brat",
"ac" -> "brac", "u" -> "bru", "am" -> "bram", "es" -> "bres",
"no" -> "brno", "og" -> "brog"|>,
"kr" -> <|"o" -> "kro", "as" -> "kras", "y" -> "kry", "in" -> "krin",
"i" -> "kri", "u" -> "kru", "am" -> "kram", "es" -> "kres", "og" -> "krog"|>,
"sr" -> <|"in" -> "srin", "i" -> "sri"|>,
"y" -> <|"o" -> "yo", "al" -> "yal", "p" -> "yp", "ar" -> "yar", "v" -> "yv",
"as" -> "yas", "in" -> "yin", "i" -> "yi", "pr" -> "ypr", "er" -> "yer",
"os" -> "yos", "at" -> "yat", "ac" -> "yac", "u" -> "yu", "am" -> "yam",
"es" -> "yes", "og" -> "yog"|>, "nb" -> <|"c" -> "nbc"|>,
"mo" -> <|"h" -> "moh", "he" -> "mohe", "li" -> "moli", "b" -> "mob",
"c" -> "moc", "n" -> "mon", "o" -> "moo", "ne" -> "mone", "na" -> "mona",
"p" -> "mop", "s" -> "mos", "sc" -> "mosc", "ti" -> "moti", "v" -> "mov",
"ni" -> "moni", "ga" -> "moga", "se" -> "mose", "rb" -> "morb",
"te" -> "mote", "i" -> "moi", "la" -> "mola", "nd" -> "mond", "ho" -> "moho",
"lu" -> "molu", "w" -> "mow", "re" -> "more", "os" -> "moos",
"ir" -> "moir", "tl" -> "motl", "bi" -> "mobi", "at" -> "moat",
"rn" -> "morn", "ra" -> "mora", "th" -> "moth", "u" -> "mou", "no" -> "mono",
"ds" -> "mods", "rg" -> "morg", "ts" -> "mots", "og" -> "moog"|>,
"tc" -> <|"h" -> "tch"|>,
"ru" -> <|"h" -> "ruh", "li" -> "ruli", "be" -> "rube", "b" -> "rub",
"c" -> "ruc", "n" -> "run", "f" -> "ruf", "ne" -> "rune", "na" -> "runa",
"p" -> "rup", "s" -> "rus", "k" -> "ruk", "ni" -> "runi", "se" -> "ruse",
"br" -> "rubr", "mo" -> "rumo", "in" -> "ruin", "i" -> "rui", "ba" -> "ruba",
"nd" -> "rund", "dy" -> "rudy", "ta" -> "ruta", "pt" -> "rupt",
"tl" -> "rutl", "bi" -> "rubi", "ra" -> "rura", "th" -> "ruth",
"es" -> "rues", "no" -> "runo", "ts" -> "ruts"|>,
"rh" -> <|"o" -> "rho", "y" -> "rhy", "in" -> "rhin", "i" -> "rhi",
"eu" -> "rheu", "os" -> "rhos", "u" -> "rhu", "es" -> "rhes"|>,
"ag" -> <|"h" -> "agh", "li" -> "agli", "n" -> "agn", "o" -> "ago",
"ne" -> "agne", "ar" -> "agar", "ni" -> "agni", "as" -> "agas",
"in" -> "agin", "i" -> "agi", "la" -> "agla", "er" -> "ager", "re" -> "agre",
"at" -> "agat", "ra" -> "agra", "u" -> "agu", "am" -> "agam",
"es" -> "ages", "no" -> "agno", "og" -> "agog"|>, "cd" -> <||>,
"in" -> <|"h" -> "inh", "he" -> "inhe", "b" -> "inb", "c" -> "inc",
"n" -> "inn", "o" -> "ino", "f" -> "inf", "ne" -> "inne", "na" -> "inna",
"al" -> "inal", "si" -> "insi", "p" -> "inp", "s" -> "ins", "cl" -> "incl",
"ar" -> "inar", "k" -> "ink", "ca" -> "inca", "sc" -> "insc", "ti" -> "inti",
"v" -> "inv", "cr" -> "incr", "fe" -> "infe", "co" -> "inco",
"ni" -> "inni", "cu" -> "incu", "ga" -> "inga", "ge" -> "inge",
"as" -> "inas", "se" -> "inse", "br" -> "inbr", "mo" -> "inmo",
"ru" -> "inru", "te" -> "inte", "i" -> "ini", "la" -> "inla", "ce" -> "ince",
"dy" -> "indy", "ho" -> "inho", "er" -> "iner", "ta" -> "inta",
"w" -> "inw", "au" -> "inau", "at" -> "inat", "fr" -> "infr", "ac" -> "inac",
"pa" -> "inpa", "u" -> "inu", "pu" -> "inpu", "am" -> "inam",
"es" -> "ines", "no" -> "inno", "fl" -> "infl"|>,
...
"u" -> "flu", "am" -> "flam", "es" -> "fles", "og" -> "flog"|>,
"mc" -> <|"b" -> "mcb", "c" -> "mcc", "n" -> "mcn", "f" -> "mcf",
"ne" -> "mcne", "na" -> "mcna", "p" -> "mcp", "cl" -> "mccl", "k" -> "mck",
"ca" -> "mcca", "v" -> "mcv", "cr" -> "mccr", "co" -> "mcco", "cu" -> "mccu",
"ge" -> "mcge", "br" -> "mcbr", "in" -> "mcin", "i" -> "mci",
"la" -> "mcla", "lu" -> "mclu"|>, "lv" -> <|"o" -> "lvo"|>,
"ts" -> <|"ar" -> "tsar", "i" -> "tsi", "w" -> "tsw", "u" -> "tsu"|>,
"og" -> <|"li" -> "ogli", "b" -> "ogb", "i" -> "ogi", "re" -> "ogre"|>|>
and we see there's a lot of patterns that will work. This is unsurprising, but just shows that the exhaustive search will be slow.
The final leaves are't all valid words, but are instead valid patterns.
We can fill out the entirety of the trie starting from og
without too much work though:
fillTrie[classes[[-1]], classes, validStartQ, 4]
<|"li" -> <|"n" -> "oglin"|>,
"b" -> <|"o" -> <|"mo" -> <|"s" -> <|"h" -> "ogbomosh",
"ho" -> "ogbomosho"|>|>|>|>, "i" -> <|"lv" -> <|"y" -> "ogilvy"|>|>,
"re" -> <|"s" -> <|"s" -> <|"es" -> "ogresses"|>,
"se" -> <|"s" -> "ogresses"|>|>, "i" -> <|"s" -> <|"h" -> "ogreish"|>|>|>|>
You'll notice that we only bottom out here. There are valid words (ogre
, ogress
) that we've skipped. You'd need to write extra logic to pull those as you build that I don't really feel like doing since it'd require yet another word valid word check.
Or if you want to build iteratively, you can do that from the existing trie. Here we'll just add another level of depth to the existing one
wat3 =
Map[
fillTrie[#, classes, validStartQ, 0] &,
wat,
{2}
];
and here are some of the valid prefixes we get from that
pullLeaves[v_] :=
Which[
AssociationQ[v], Values[v],
StringQ[v], v,
True, Map[pullLeaves, v]
];
allPrefixes = Flatten@Nest[pullLeaves , wat3, 3];
RandomSample[allPrefixes, 100]
{"haci", "cindy", "lippm", "braces", "soni", "hepp", "liki", "rayo", "clui", \
"hamh", "prebe", "infeas", "erys", "smok", "ambu", "fremo", "hover", "copla", \
"luaus", "hess", "halog", "sinc", "viri", "pratin", "biki", "sires", "koal", \
"sach", "refec", "unini", "libre", "hooli", "ructi", "cowpa", "teami", "fow", \
"arcs", "reinco", "tabas", "vibr", "parana", "acycl", "cube", "scorb", "osier", \
"noses", "niob", "sou", "recros", "ashra", "scher", "cluin", "scuba", "basen", \
"refin", "inept", "inho", "novi", "reino", "atona", "auber", "inhos", "lithu", \
"where", "viti", "shc", "cringe", "clare", "viru", "stasi", "copu", "lays", \
"fiat", "nouga", "catere", "yond", "morav", "lushe", "albani", "seagu", \
"cruxe", "reatta", "hipb", "reauth", "sunb", "yacc", "cairn", "runs", "tabo", \
"neck", "serfs", "noos", "casi", "senio", "rawn", "altern", "orgas", "sixe", \
"ascen", "poisi"}
and to show why DictionaryLookup
is so slow, here's one of the valid words it accepts from that list
DictionaryLookup["erys*", IgnoreCase -> True]
{"erysipelas"}
This is a very, very obscure word. It also takes HBO
.
Finally, here's a way to do this only with classes you care about. We'll take only the elements that are commonly found in humans (for a given definition of common)
abundances =
QuantityMagnitude@
EntityValue[EntityClass["Element", All],
EntityProperty["Element", "HumanMolarAbundance"]];
organicElements = Pick[
classes, # > 1.*^-5 & /@ abundances
]
{"h", "b", "c", "n", "o", "f", "na", "mg", "al", "si", "p", "s", "cl", "k", \
"ca", "fe", "zn", "br", "rb", "sr"}
and the trie is pretty quick to build with such a restricted option set
humanTrie = fillTrie["", organicElements, validStartQ, 3];
humanPrefixes = Flatten@Nest[pullLeaves, Values@humanTrie, 3];
RandomSample[humanPrefixes, 100]
{"brno", "confe", "sons", "oks", "soho", "alfalf", "ksh", "feal", "knack", \
"napo", "feca", "bobc", "hons", "bocca", "canb", "occasi", "naps", "ocho", \
"ops", "nass", "calca", "fops", "obno", "conc", "obso", "caffe", "nabok", \
"canap", "opos", "psh", "kopp", "coos", "palsi", "nop", "nonh", "cobr", "nonn", \
"cloch", "nosin", "nanos", "nons", "saloo", "scabb", "sincl", "poss", "fn", \
"conk", "sock", "hobs", "falkn", "popc", "nao", "balal", "nook", "booh", "nca", \
"cobs", "sih", "sikhs", "coals", "offsi", "copp", "offs", "poon", "sinf", \
"sif", "sorbo", "cahoo", "koal", "nans", "obsc", "pfenn", "closin", "capp", \
"clona", "cak", "feck", "conf", "foss", "falsif", "chos", "phal", "bocc", \
"sops", "aln", "coho", "pock", "brons", "caph", "sobr", "knob", "sina", "oops", \
"nbc", "cosb", "calc", "bobo", "pozn", "bosh", "hbo"}
```
elements
.DictionaryLookup[RegularExpression@StringRiffle[elements, {"(", "|", ")"}]..]
. Output length:13573
$\endgroup$