diff --git a/wordle.py b/wordle.py index dca2c1b..9d90b90 100644 --- a/wordle.py +++ b/wordle.py @@ -11,36 +11,91 @@ WORDLE_LENGTH = 5 class LetterResult(Enum): """Is an individual letter in a word in the result?""" - CORRECT = 'C' - MOVE = 'M' - INCORRECT = 'I' - UNKNOWN = 'U' + + CORRECT = "C" + MOVE = "M" + INCORRECT = "I" + UNKNOWN = "U" class InvalidWord(Exception): """Thrown when an input word is not a valid Wordle.""" + pass _wordle_dictionary = set() -_invalid_words = set([ - 'staia', 'erept', 'boily', 'bolty', 'pindy', 'hyrse', 'hirse', 'retan', 'sisel', - 'skeel', 'telae', 'genae', 'beata', 'beala', 'macco', 'beele', 'divet', 'vedet', - 'stail', 'roter', 'fikie', 'muang', 'nurry', 'arara', 'araru', 'araua', 'arawa', - 'mitra', 'gotra', 'whaly', 'whalm', 'doray', 'korah', 'caroa', 'carlo', 'carot', - 'carum', 'theet', 'tebet', 'ghole', 'odell', 'sussy', 'bayal', 'balak', 'katat', - 'batak', 'bruke', 'uninn', 'undig', 'unkin', 'quito', 'petro', 'amala', - ]) +_invalid_words = set( + [ + "amala", + "arara", + "araru", + "araua", + "arawa", + "balak", + "batak", + "bayal", + "beala", + "beata", + "beele", + "boily", + "bolty", + "bruke", + "carlo", + "caroa", + "carot", + "carum", + "divet", + "doray", + "erept", + "fikie", + "genae", + "ghole", + "gotra", + "hirse", + "hyrse", + "katat", + "korah", + "macco", + "mitra", + "muang", + "nurry", + "odell", + "odell", + "petro", + "pindy", + "quito", + "retan", + "roter", + "sisel", + "skeel", + "staia", + "stail", + "sussy", + "tebet", + "telae", + "theet", + "undig", + "uninn", + "unkin", + "vedet", + "whalm", + "whaly", + ] +) def dictionary(): if not _wordle_dictionary: - with open('words_alpha.txt') as word_file: + with open("words_alpha.txt") as word_file: all_words = word_file.read().split() _wordle_dictionary.update( - filter(lambda w: len(w) == WORDLE_LENGTH and w not in _invalid_words, all_words)) + filter( + lambda w: len(w) == WORDLE_LENGTH and w not in _invalid_words, all_words + ) + ) return _wordle_dictionary @@ -82,12 +137,12 @@ def grade_word(target, guess): def display_result(result, text): opening = { - LetterResult.CORRECT: '\033[92m', - LetterResult.MOVE: '\033[33m', - LetterResult.INCORRECT: '\033[36m', - LetterResult.UNKNOWN: '', + LetterResult.CORRECT: "\033[92m", + LetterResult.MOVE: "\033[33m", + LetterResult.INCORRECT: "\033[36m", + LetterResult.UNKNOWN: "", } - closing = '\033[0m' + closing = "\033[0m" return f"{opening[result]}{text}{closing}" @@ -102,11 +157,13 @@ def success_result(result): def analyze_dictionary(wordle_dictionary): # Word Position, Letter: Count - position_matches = [defaultdict(int), - defaultdict(int), - defaultdict(int), - defaultdict(int), - defaultdict(int)] + position_matches = [ + defaultdict(int), + defaultdict(int), + defaultdict(int), + defaultdict(int), + defaultdict(int), + ] # Letter: Count word_matches = defaultdict(int) @@ -118,7 +175,7 @@ def analyze_dictionary(wordle_dictionary): for index in range(len(word)): letter = word[index] - assert (letter in string.ascii_lowercase) + assert letter in string.ascii_lowercase position_matches[index][letter] += 1 return position_matches, word_matches @@ -156,8 +213,7 @@ def scored_words(wordle_dictionary=dictionary()): return [(word, scored_words[word]) for word in result] -class Constraints(): - +class Constraints: def __init__(self): # Array of known letters in result with None for unknown. self.correct = [None] * WORDLE_LENGTH @@ -170,7 +226,6 @@ class Constraints(): # List of LetterResult values. def update_graded(self, guess, grade): - guess = guess.lower() new_count = defaultdict(int) @@ -192,7 +247,6 @@ class Constraints(): self.count[letter] = max(c, self.count[letter]) def matches(self, guess): - counts = defaultdict(int) # All known correct letters in place. @@ -222,10 +276,18 @@ def filter_dictionary(constraints, wordle_dictionary=dictionary()): return set(filter(lambda w: constraints.matches(w), wordle_dictionary)) -if __name__ == '__main__': +if __name__ == "__main__": constraints = Constraints() - constraints.update_graded('cares', [LetterResult.INCORRECT, LetterResult.INCORRECT, - LetterResult.INCORRECT, LetterResult.INCORRECT, LetterResult.INCORRECT]) + constraints.update_graded( + "cares", + [ + LetterResult.INCORRECT, + LetterResult.INCORRECT, + LetterResult.INCORRECT, + LetterResult.INCORRECT, + LetterResult.INCORRECT, + ], + ) valid_words = filter_dictionary(constraints)