# # 1. Read word list # word list is long (over 200,000 words!) so we # just print the first 100; this goes away later # 2. Eliminate words that are not exactly 5 characters long # 3. Read pattern, characters that must be in the word ("good # letters"), characters that are not in the word ("bad # letters") # print them to verify they are right, and then quit; # this goes away later # 3a. Check no letters are both good and bad # 4. Eliminate words with bad letters # 4a. Make all letters lower case # 5. Eliminate words with no good letters # 6. Eliminate words that do not match a pattern # import re import sys # # the word list # wordlist = "/usr/share/dict/words" # # get pattern, good, bad letters # try: pat = input("Pattern: ") good = input("Letters you know are in the word: ") bad = input("Letters you know are not in the word: ") except Exception as msg: print(msg) sys.exit(1) # # compile the pattern # comppat = re.compile(pat, re.IGNORECASE) # # make good, bad letters all lower case # good = good.lower() bad = bad.lower() # # print them # print(f"Pattern: '{pat}'") print(f"Good: '{good}'") print(f"Bad: '{bad}'") # # sanity check: no letters are both good and bad # # doing this with sets is the easiest way # goodset = set(good) badset = set(bad) commonchars = goodset & badset # see if any letters are both good and bad if commonchars: # yes -- say what they are and this isn't allowed print("These letters are both good and bad: ", end='') c = '' # list them in alphabetical order for x in sorted(commonchars): c = c + x print(f"'{c}'; not allowed!") sys.exit(1) # # open the word list # try: wl = open(wordlist, "r") except Exception as msg: print(msg) sys.exit(1) # # return True if no bad letters in word # def nobad(w): for x in bad: if x in w: return False return True # # return True if all good characters in word # note you have to check the number of each # good letter as the wordle answer may have # duplicate letters (like in 'honor', a valid # answer), so if I have 'ooo' as good letters, # checking that each 'o' i in the word is True # but should be False as 'honor' has 2 o's, not 3 # def allgood(w): for x in good: if good.count(x) != word.count(x): return False return True # # return True if a match, False if not # def ismatch(w): if comppat.fullmatch(w): return True return False # # print possible words # for word in wl: # remove trailing (and leading!) space word = word.strip() # make all letters lower case word = word.lower() # skip words not exactly 5 characters long, or # with bad letters, or with not all good letters, # or that does not match the given pattern if len(word) == 5 and ismatch(word) and allgood(word) and nobad(word): print(word)