Skip to content

Instantly share code, notes, and snippets.

@ruggeri
Created April 24, 2022 06:39
Show Gist options
  • Save ruggeri/a0b536fbb84387b4620e22e605b48050 to your computer and use it in GitHub Desktop.
Save ruggeri/a0b536fbb84387b4620e22e605b48050 to your computer and use it in GitHub Desktop.
import random
import re
import string
def load_dictionary():
with open("dictionary.txt") as f:
return f.read().splitlines()
def filter_dictionary(dictionary):
new_dictionary = []
for word in dictionary:
if not re.match("^[a-z]{5}$", word):
continue
word_letters = set()
keep_word = True
for c in word:
if c in word_letters:
keep_word = False
break
word_letters.add(c)
num_vowels = 0
for c in "aeiou":
if c in word:
num_vowels += 1
if num_vowels > 2:
keep_word = False
if keep_word :
new_dictionary.append(word)
return new_dictionary
DICTIONARY = load_dictionary()
DICTIONARY = filter_dictionary(DICTIONARY)
print(f"Num words in dictionary: {len(DICTIONARY)}")
def new_letter_counts():
letter_counts = {}
for c in string.ascii_lowercase:
letter_counts[c] = 1
return letter_counts
def valid_word(letter_counts, word):
for c in word:
if c not in letter_counts:
return False
if letter_counts[c] != 1:
return False
return True
def decrement_letter_counts(letter_counts, word):
for c in word:
if letter_counts[c] == 0:
raise "Unexpected double decrement?"
letter_counts[c] = 0
def increment_letter_counts(letter_counts, word):
for c in word:
if letter_counts[c] == 1:
raise "Unexpected double increment?"
letter_counts[c] = 1
def choose_next_word(dictionary, letter_counts):
for word in dictionary:
if valid_word(letter_counts, word):
return word
return None
NUM_TRIES = 10
def extend_chosen_words(dictionary, chosen_words, letter_counts):
# No more extension needed.
if len(chosen_words) == 4:
return []
for _ in range(NUM_TRIES):
random.shuffle(dictionary)
next_word = choose_next_word(dictionary, letter_counts)
if next_word is None:
return None
decrement_letter_counts(letter_counts, next_word)
more_words = extend_chosen_words(
dictionary,
chosen_words + [next_word],
letter_counts
)
if more_words is not None:
return [next_word] + more_words
else:
increment_letter_counts(letter_counts, next_word)
return None
def choose_four_words(dictionary):
letter_counts = new_letter_counts()
initial_chosen_words = []
for preword in initial_chosen_words:
decrement_letter_counts(letter_counts, preword)
return initial_chosen_words + extend_chosen_words(
dictionary,
initial_chosen_words,
letter_counts
)
def main():
chosen_words = choose_four_words(DICTIONARY)
print(chosen_words)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment