Cheating at anagrams with Python

How to cheat at anagram word puzzles (or Scrabble) with Python.
Python
Just for fun
Published

June 12, 2019

My daughter recently challenged me to an instant messenging Anagrams game where the goal is to generate the most words using a starting set of letters. Each word scores points and longer words are worth more points.

Somehow, I managed to lose. Inconceivable. Which brings us to some words of wisdom:

Old age and treachery will always defeat youth and skill.

English Proverb

Below is a snippet of Python code that identifies words in the Unix word dictionary file (available on Mac OS X as well) that can be created with a given set of letters. The words are returned from longest to shortest, to gain the most points as quickly as possible.

# Return words that can be constructed with a set of letters
# - uses the words list available in most Unix systems, including Mac OS X

# Define constants
wordfile = '/usr/share/dict/words' # source of wordlist
min_word_length = 4

# Create dictionary of how many of each available letter
starting = input("Letters available: ")
avail_letters = {} # dictionary with key = letter and value = # available
for letter in starting.strip().lower():
    avail_letters[letter] = avail_letters.get(letter, 0) + 1 # default 0

# Build list of possible words    
words = []
with open(wordfile) as f:
    for line in f:
        word = line.strip().lower()
        success = True
        if len(word) < min_word_length: # word too short, skip it
            continue # go to next word in file
        for letter in set(word):
            if avail_letters.get(letter, 0) < word.count(letter): # not enough letters
                success = False
                break
        if success:
            words.append(word) # add to found word list
        if len(words) >= 100: # don't return more than 100 words
            break

# Return nested sort of unique words
# - by longest first, and alphabetically within same length
words = sorted(sorted(list(set(words))), key = lambda x: -len(x))
for word in words:
    print(len(word), word)

Sample Output

Letters available: hutocs
6 schout
6 scouth
5 chous
5 couth
5 hocus
5 scout
5 shout
5 socht
5 south
5 thuoc
5 touch
4 chou
4 chut
4 cosh
4 cost
4 coth
4 cush
4 host
4 huso
4 ocht
4 otus
4 ouch
4 oust

The result