Useless information: If you share a New York Times subscription with someone else, and you both play Wordle, you can maintain your individual streak data as long as you use different browsers to access the game. Using the WordleBot, however, requires a New York Times login, and Wordle will not maintain multiple users’ streak data when the users login using the same account credentials.

One of the interesting bits of information that the WordleBot provides is the number of possible words that were available at each step in the game, letting you know the degree to which your solution was lucky or predestined.

After finishing the Regular Expression Dictionary I decided to replicate this functionality. I created an app that would list possible Wordle words, given a series of guesses and the colors assigned by Wordle in response.

The service that I wrote for this application accepts two strings, one of the guesses and one with the corresponding colors. If one were wondering, for example, given these guesses, how many alternatives existed to QUOTA for this Wordle:

default

you would provide the strings SMARTTABLEATTIC and BBYBYYYBBBYYBBB,

This service (and an associated rudimentary front end) have been up and running for a few months, and they have allowed my Wordle companion to see what other possible solutions exist. Until today, when it responded

default

The code records the following information from the supplied letters and colors:

  • A list of the letters that are known not to be in the solution word.
  • A list of the letters that must be in the solution word.
  • For each position, a list of the letters that must to be at that position.
  • For each position, a list of the letters that must not be at that position.  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@app.route("/red/wordle/",methods=['GET', 'OPTIONS'])
def wordle():
letters = request.args.get('letters').upper() # Concatenation of the guesses
colors = request.args.get('colors').upper()   # and their colors (B,Y, or G)

# Input validation not shown

never = ""
always =  [ "","","","",""  ]
elsewhere =  [ "","","","",""  ]
required = ""

for i in range(0,nwords):
        words.append(letters[i*5:i*5+5])
        for j in range(0,5) :
                if colors[i*5+j] == 'B' :
                        never += words[i][j] 
                elif colors[i*5+j] == 'G' :
                        always[j] = words[i][j]
                        required += words[i][j]
                else: # yellow
                        elsewhere[j] += words[i][j]
                        required += words[i][j]

Lines 16-17 assume that if a letter is colored B (black), it does not appear in the answer. In fact, as in the case of ATTIC, if the guess contains multiple instances of a letter, all of which are incorrectly placed, only the first instance is colored Y (yellow). This represents a choice by the Wordle UI designer, since it would be equally reasonable to color all the instances yellow.

The subtler error is in the way the parsing code represents the information provided by the game. The always and elsewhere arrays are meant to contain the characters at each position that must be present (green) or are required elsewhere in the word (yellow). Given the behavior of the game, it would make more sense to record for each position which letters are required (green) and which are prohibited (yellow or black) and separately maintain the global lists of required and prohibited words.

The corrected code changes the order in which the colors are processed, and only adds letters to the never array if they are not already in the required array.

never = ""
always =  [ "","","","",""  ]
prohibited =  [ "","","","",""  ]
required = ""

for i in range(0,nwords):
        words.append(letters[i*5:i*5+5])
        for j in range(0,5) :
                if colors[i*5+j] == 'G' :
                        always[j] = words[i][j]
                        required += words[i][j]
                elif colors[i*5+j] == 'Y' :
                        prohibited[j] += words[i][j]
                        required += words[i][j]
                else : 
                        prohibited[j] = words[i][j]
                        # It's only a never if it hasn't already shown up as yellow
                        if not (words[i][j] in required) : 
                                never += words[i][j] 

After deploying the modified code, the correct result is returned, revealing two common words to be valid: QUOTA and JUNTA.

default