Like many this holiday season, my family has become hooked on Wordle and my mind immediately turned to what an optimal opening would be…

Initially I started packing vowels into the first word like ALIEN or SAUCE - which is fine but a better strategy would also:

  • Provide guidance on the second word (to give you enough to solve in three)
  • Cover at least 9 unique letters over the two words
  • Provide a weighted score based on the number of Yellows and Greens you could get

Jumping straight to the end, the following are my three favorite openings: image

How to Use

Firstly pick one of the purple words as your first word.

If you get a Yellow - use the matching vertical word which moves the letter to a new position and provides four new letters.

If you get nothing on the first - use the backup word at the bottom to give you five new letters.

image

The Approach & Code

The first step in coming up with these openings is to take a database of all five letter words and give each word that provides 1 point for each yellow it gets on all other words and an additional 2 points if it gets a green.

Tweaking these weights will provide different openings.

wordscores = []
for word in words:
    if len({x for x in word}) >= 5: # We only want words that have 
        score = {'word':word,'yellow':0,'green':0}
        for testword in words:
            score['yellow'] += sum([1 if x in testword else 0 for x in {x for x in word}])
            score['green']  += sum([1 if word[i]==testword[i] else 0 for i in range(0,5)])
        score['score'] = score['yellow'] + score['green']*2
        wordscores.append(score)

wordscores.sort(key=lambda x: x['score'], reverse=True)
wordscores[:10]

Which provides

[{'word': 'stare', 'yellow': 7295, 'green': 2168, 'score': 11631},
 {'word': 'raise', 'yellow': 7331, 'green': 2142, 'score': 11615},
 {'word': 'slate', 'yellow': 6973, 'green': 2310, 'score': 11593},
 {'word': 'sorel', 'yellow': 6816, 'green': 2363, 'score': 11542},
 {'word': 'saute', 'yellow': 6691, 'green': 2414, 'score': 11519},
 {'word': 'snare', 'yellow': 7126, 'green': 2195, 'score': 11516},
 {'word': 'carse', 'yellow': 6946, 'green': 2272, 'score': 11490},
 {'word': 'caret', 'yellow': 6889, 'green': 2291, 'score': 11471},
 {'word': 'arise', 'yellow': 7331, 'green': 2052, 'score': 11435},
 {'word': 'arose', 'yellow': 7393, 'green': 2015, 'score': 11423}]

Which by themselves are perfectly good opening words, but we also want words that have good follow up options

openings = [{'totalscore':x['score']*6, 'word':x['word']} for x in wordscores]
for firstword in openings:
    for word in wordscores:
        if (len({y for y in firstword['word']+word['word']})>=10):
            firstword['secondword0'] = word['word']
            firstword['totalscore'] += word['score']
            break
    for i in range(0,5):
        for word in wordscores:
            if (firstword['word'][i] != word['word'][i]) and (firstword['word'][i] in word['word']) and (len({y for y in firstword['word']+word['word']})>=9):
                firstword['secondword{}'.format(i+1)] = word['word']
                firstword['totalscore'] += word['score']
                break

openings.sort(key=lambda x: x['totalscore'], reverse=True)
openings[:5]

Which provides the opening combos:

[{'totalscore': 127190, 'word': 'sorel', 'secondword0': 'canty', 'secondword1': 'tansy', 'secondword2': 'atony', 'secondword3': 'rainy', 'secondword4': 'thane', 'secondword5': 'laity'}
,{'totalscore': 126635, 'word': 'slate', 'secondword0': 'corny', 'secondword1': 'noisy', 'secondword2': 'roily', 'secondword3': 'rainy', 'secondword4': 'court', 'secondword5': 'coney'}
,{'totalscore': 125889, 'word': 'saute', 'secondword0': 'roily', 'secondword1': 'loris', 'secondword2': 'coaly', 'secondword3': 'curly', 'secondword4': 'droit', 'secondword5': 'oriel'}
,{'totalscore': 125667, 'word': 'saint', 'secondword0': 'poler', 'secondword1': 'corse', 'secondword2': 'blare', 'secondword3': 'oiler', 'secondword4': 'coney', 'secondword5': 'route'}
,{'totalscore': 125585, 'word': 'stare', 'secondword0': 'doily', 'secondword1': 'noisy', 'secondword2': 'point', 'secondword3': 'daily', 'secondword4': 'roily', 'secondword5': 'coney'}]