# # 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 # 7. If word list named on command line, use it # 8. Now clean up a few things # -- empty pattern causes error; check for it # -- check for invalid patterns *before* asking for other inputs # -- eliminate printing pattern, and good and bad letters # import re import sys # # the word list # wordlist = "/usr/share/dict/words" # # see if something is named on the command line # if one argument, treat it as a word list file # error if more than one argument # if len(sys.argv) == 2: wordlist = sys.argv[1] elif len(sys.argv) > 2: print("One word list at a time, please!") sys.exit(1) # # get pattern, good, bad letters # try: pat = input("Pattern: ") except Exception as msg: print(msg) sys.exit(1) # # compile the pattern, if a pattern is given # if pat: try: comppat = re.compile(pat, re.IGNORECASE) except Exception as msg: print("Error in pattern:", msg) sys.exit(1) # # get pattern, good, bad letters # try: 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) # # make good, bad letters all lower case # good = good.lower() bad = bad.lower() # # 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 not pat or 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)