Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you want to find words whose letters and frequency thereof are restricted by the given phrase, you can construct a regex to do this for you:</p> <pre><code>sentence = "Ziegler's Giant Bar" # count how many times each letter occurs in the # sentence (ignoring case, and removing non-letters) counts = Hash.new(0) sentence.downcase.gsub(/[^a-z]/,'').split(//).each do |letter| counts[letter] += 1 end letters = counts.keys.join length = counts.values.inject { |a,b| a + b } # construct a regex that matches upto that many occurences # of only those letters, ignoring non-letters # (in a positive look ahead) length_regex = /(?=^(?:[^a-z]*[#{letters}]){1,#{length}}[^a-z]*$)/i # construct regexes that matches each letter up to its # proper frequency (in a positive look ahead) count_regexes = counts.map do |letter, count| /(?=^(?:[^#{letter}]*#{letter}){0,#{count}}[^#{letter}]*$)/i end # combine the regexes, to form a regex that will only # match words that are made of a subset of the letters in the string regex = /#{length_regex}#{count_regexes.join('')}/ # open a big file of words, and find all the ones that match words = File.open("/usr/share/dict/words") do |f| f.map { |word| word.chomp }.find_all { |word| regex =~ word } end words.length #=&gt; 3182 words #=&gt; ["A", "a", "aa", "aal", "aalii", "Aani", "Ab", "aba", "abaiser", "Abantes", "Abaris", "abas", "abase", "abaser", "Abasgi", "abate", "abater", "abatis", ... "ba", "baa", "Baal", "baal", "Baalist", "Baalite", "Baalize", "baar", "bae", "Baeria", "baetzner", "bag", "baga", "bagani", "bagatine", "bagel", "bagganet", ... "eager", "eagle", "eaglet", "eagre", "ean", "ear", "earing", "earl", "earlet", "earn", "earner", "earnest", "earring", "eartab", "ease", "easel", "easer", ... "gab", "Gabe", "gabi", "gable", "gablet", "Gabriel", "Gael", "gaen", "gaet", "gag", "gagate", "gage", "gageable", "gagee", "gageite", "gager", "Gaia", ... "Iberian", "Iberis", "iberite", "ibis", "Ibsenite", "ie", "Ierne", "Igara", "Igbira", "ignatia", "ignite", "igniter", "Ila", "ilesite", "ilia", "Ilian", ... "laang", "lab", "Laban", "labia", "labiate", "labis", "labra", "labret", "laet", "laeti", "lag", "lagan", "lagen", "lagena", "lager", "laggar", "laggen", ... "Nabal", "Nabalite", "nabla", "nable", "nabs", "nae", "naegate", "naegates", "nael", "nag", "Naga", "naga", "Nagari", "nagger", "naggle", "nagster", "Naias", ... "Rab", "rab", "rabat", "rabatine", "Rabi", "rabies", "rabinet", "rag", "raga", "rage", "rager", "raggee", "ragger", "raggil", "raggle", "raging", "raglan", ... "sa", "saa", "Saan", "sab", "Saba", "Sabal", "Saban", "sabe", "saber", "saberleg", "Sabia", "Sabian", "Sabina", "sabina", "Sabine", "sabine", "Sabir", ... "tabes", "Tabira", "tabla", "table", "tabler", "tables", "tabling", "Tabriz", "tae", "tael", "taen", "taenia", "taenial", "tag", "Tagabilis", "Tagal", ... "zest", "zeta", "ziara", "ziarat", "zibeline", "zibet", "ziega", "zieger", "zig", "zing", "zingel", "Zingiber", "zira", "zirai", "Zirbanit", "Zirian"] </code></pre> <p>Positive lookaheads let you make a regex that matches a <em>position</em> in the string where some specified pattern matches without consuming the part of the string that matches. We use them here to match the same string against multiple patterns in a single regex. The position only matches if all our patterns match.</p> <p>If we allow infinite reuse of letters from the original phrase (like Knuth did according to <a href="https://stackoverflow.com/users/98221/glenra">glenra</a>'s comment), then it's even easier to construct a regex:</p> <pre><code>sentence = "Ziegler's Giant Bar" # find all the letters in the sentence letters = sentence.downcase.gsub(/[^a-z]/,'').split(//).uniq # construct a regex that matches any line in which # the only letters used are the ones in the sentence regex = /^([^a-z]|[#{letters.join}])*$/i # open a big file of words, and find all the ones that match words = File.open("/usr/share/dict/words") do |f| f.map { |word| word.chomp }.find_all { |word| regex =~ word } end words.length #=&gt; 6725 words #=&gt; ["A", "a", "aa", "aal", "aalii", "Aani", "Ab", "aba", "abaiser", "abalienate", ... "azine", "B", "b", "ba", "baa", "Baal", "baal", "Baalist", "Baalite", "Baalize", "baar", "Bab", "baba", "babai", "Babbie", "Babbitt", "babbitt", ... "Britannian", "britten", "brittle", "brittleness", "brittling", "Briza", "brizz", "E", "e", "ea", "eager", "eagerness", "eagle", "eagless", "eaglet", "eagre", "ean", "ear", "earing", "earl", "earless", "earlet", "earliness", ... "eternalize", "eternalness", "eternize", "etesian", "etna", "Etnean", "Etta", "Ettarre", "ettle", "ezba", "Ezra", "G", "g", "Ga", "ga", "gab", "gabber", "gabble", "gabbler", "Gabe", "gabelle", "gabeller", "gabgab", "gabi", "gable", ... "grittiness", "grittle", "Grizel", "Grizzel", "grizzle", "grizzler", "grr", "I", "i", "iba", "Iban", "Ibanag", "Iberes", "Iberi", "Iberia", "Iberian", ... "itinerarian", "itinerate", "its", "Itza", "Izar", "izar", "izle", "iztle", "L", "l", "la", "laager", "laang", "lab", "Laban", "labara", "labba", "labber", ... "litter", "litterer", "little", "littleness", "littling", "littress", "litz", "Liz", "Lizzie", "Llanberisslate", "N", "n", "na", "naa", "Naassenes", "nab", "Nabal", "Nabalite", "Nabataean", "Nabatean", "nabber", "nabla", "nable", ... "niter", "nitraniline", "nitrate", "nitratine", "Nitrian", "nitrile", "nitrite", "nitter", "R", "r", "ra", "Rab", "rab", "rabanna", "rabat", "rabatine", "rabatte", "rabbanist", "rabbanite", "rabbet", "rabbeting", ... "riteless", "ritelessness", "ritling", "rittingerite", "rizzar", "rizzle", "S", "s", "sa", "saa", "Saan", "sab", "Saba", "Sabaean", "sabaigrass", "Sabaist", ... "strigine", "string", "stringene", "stringent", "stringentness", "stringer", "stringiness", "stringing", "stringless", "strit", "T", "t", "ta", "taa", "Taal", "taar", "Tab", "tab", "tabaret", "tabbarea", "tabber", "tabbinet", ... "tsessebe", "tsetse", "tsia", "tsine", "tst", "tzaritza", "Tzental", "Z", "z", "za", "Zabaean", "zabeta", "Zabian", "zabra", "zabti", "zabtie", "zag", "zain", ... "Zirian", "Zirianian", "Zizania", "Zizia", "zizz"] </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload