Wordle-GPU is an elimination-based command-line solver for the game Wordle, written in C++ and HIP to run on AMD GPU.
Demo (left: solver, right: a Wordle GUI):
- CMake >= 3.12
- ROCm >= 5.0
- AMD GPU to run the program (current repo is configured and tuned for MI250X/gfx90a)
Clone the repository, configure using CMake, and build the code:
git clone https://github.com/mrowan137/wordle-gpu.git
cd wordle-gpu
mkdir build && cd build
cmake ..
make -j
Sample runtime configuration is as follows:
export HSA_XNACK=0
export ROCR_VISIBLE_DEVICES=0
For a system with Slurm, the code can be run with (from the build
directory):
srun -n 1 -G 1 --unbuffered wordle-gpu.exe ../src/guesses.txt ../src/solutions.txt [--hard]
or use the helper script run.sh
:
../run.sh [--hard]
The argument --hard
is an optional positional argument setting the Wordle
difficulty: 'hard mode' enforces that guesses must incorporate the clues; the
default is 'easy' mode, where any guess from guesses.txt
is allowed.
After startup, the solver proceeds in rounds, prompting for a 'clue' which is
input in a 10-character format, where the first 5 denote 'colors' and last 5
denote 'letters' of the clue. For the 0th round, the accepted guess is
??????????
, which indicates to the solver to compute the best guess without
any clue information. For subsequent rounds, the valid clue format is:
x
for gray, indicating the guess letter does not appear in the solution.y
for yellow, indicating the guess letter appears in the solution but not at that positiong
for green, indicating the guess letter appears in the solution with correct position
Example:
- Guess =
debug
, solution =beans
→ clue =xgyxxdebug
- Second letter is correct with correct position, third letter is correct with an incorrect position, and the other letters are incorrect
The program can be exited by inputting q
at the prompt.
Wordle-GPU considers all triplets (guess, test, solution) to calculate, for each valid guess word, the average number of solution eliminations; 'test' denotes a trial solution from the remaining solution words. Given 'guess' and 'solution,' the corresponding clue is determined, and the tally of eliminated words for 'guess' is incremented if the clue eliminates 'test.' In this way, a tally of words eliminated by 'guess' is computed, for all valid combinations of 'test' & 'solution.' The 'best' guess is defined as the one that eliminates the most words (averaged over all remaining 'solution' words). In case of a tie, a word from the remaining solutions is preferred, since it could be the solution.
By simulating a game with each possible solution, the average number of guesses to solution, as well as percentage of winnable games, is computed for a selection of 'best' initial guesses, i.e. the top 10 in terms of initial-round eliminations. Defining 'best' as most solution eliminations is but one choice of objective function; it is interesting to note that 'tiare,' while having lesser 1st-round average number of eliminated solutions than 'roate,' results in a lower average number of guesses to solution, and, in hard mode, a higher percentage of winnable games.
Rank | Initial guess | 1st-round avg. number of eliminated solution words | Avg. number of guesses to solution | % winnable games | Appears in solutions.txt? | ||
---|---|---|---|---|---|---|---|
Easy mode | Hard mode | Easy mode | Hard mode | ||||
1 | roate | 2254.58/2315 (97.3901%) | 3.49201 | 3.61598 | 100% | 99.6112% | No |
2 | tiare | 2254.07/2315 (97.3680%) | 3.46868 | 3.58359 | 100% | 99.7840% | No |
3 | raise | 2254.00/2315 (97.3650%) | 3.49503 | 3.63153 | 100% | 99.3089% | Yes |
4 | raile | 2253.67/2315 (97.3508%) | 3.48510 | 3.61253 | 100% | 99.6112% | No |
5 | soare | 2252.70/2315 (97.3089%) | 3.48510 | 3.63110 | 100% | 99.4384% | No |
6 | arise | 2251.27/2315 (97.2471%) | 3.51404 | 3.64104 | 100% | 99.3089% | Yes |
7 | irate | 2251.22/2315 (97.2449%) | 3.49806 | 3.61598 | 100% | 99.5248% | Yes |
8 | orate | 2251.11/2315 (97.2402%) | 3.50022 | 3.61555 | 100% | 99.5680% | No |
9 | ariel | 2249.71/2315 (97.1797%) | 3.50022 | 3.61253 | 100% | 99.6544% | No |
10 | arose | 2248.98/2315 (97.1482%) | 3.49806 | 3.61987 | 100% | 99.5248% | Yes |
Even with the 'worst' initial guesses (eliminating the fewest number of solution words, on average), it's possible to win 100% of games on easy mode, and more than 99% of games on hard mode. This is not surprising given that the 'best' guesses have an average number of guesses to solution of around 3.5–3.6; even a 'worst' guess eliminates some words, and so must be better than skipping a turn; indeed, the 'worst' initial guesses' average number of guesses to solution is less than 4.6.
Rank | Initial guess | 1st-round avg. number of eliminated solution words | Avg. number of guesses to solution | % winnable games | Appears in solutions.txt? | ||
---|---|---|---|---|---|---|---|
Easy mode | Hard mode | Easy mode | Hard mode | ||||
1 | xviii | 1199.88/2315 (51.8307%) | 4.16803 | 4.27732 | 100% | 99.0929% | No |
2 | zhuzh | 1264.08/2315 (54.6039%) | 4.11490 | 4.24881 | 100% | 99.0497% | No |
3 | immix | 1302.11/2315 (56.2467%) | 4.12354 | 4.20907 | 100% | 99.3089% | No |
4 | qajaq | 1341.39/2315 (57.9434%) | 4.18056 | 4.31274 | 100% | 98.9633% | No |
5 | jujus | 1405.29/2315 (60.7037%) | 4.12527 | 4.24104 | 100% | 99.0065% | No |
6 | jugum | 1408.13/2315 (60.8263%) | 3.98575 | 4.08035 | 100% | 99.4384% | No |
7 | gyppy | 1419.00/2315 (61.2959%) | 4.01339 | 4.13175 | 100% | 99.4816% | No |
8 | yukky | 1425.08/2315 (61.5585%) | 4.06782 | 4.21123 | 100% | 99.0497% | No |
9 | xylyl | 1426.87/2315 (61.6359%) | 4.10022 | 4.23499 | 100% | 99.2225% | No |
10 | fuffy | 1431.90/2315 (61.8531%) | 4.03672 | 4.17106 | 100% | 99.2657% | No |
For the starting guesses 'roate' (greatest average number of 1st-round solution eliminations out of any guess), 'tiare' (least average number of guesses to solution), and 'raise' (highest number of solution eliminations out of any solution word), we compute the number of guesses to solution, for each of the 2315 possible solutions. On average, the number of guesses to solution for starting word 'roate' is 3.492, for 'tiare' is 3.469, and for 'raise' is 3.495. Though the game length is marginally higher with 'raise,' it has a 1/2315 chance of being the solution, whereas 'roate' and 'tiare' are not in the solutions list and so both have a 0/2315 chance of being the solution. With all of these starting words, it is possible to win within 6 tries 100% of the time.
For hard mode, the average number of guesses to solution for 'roate' is 3.616, for 'tiare' is 3.583, and for 'raise' is 3.632. In hard mode, it's possible using the solver to still get 6+ guesses to solution, e.g. for the initial guess 'roate' and solution 'batch,' the solver computes the sequence 'roate, haunt, watch, patch, match, latch, catch, batch.' Still, 99.61% of the time it is possible to win within 6 tries using 'roate' as the starting guess, 99.78% using 'tiare', or 99.31% using 'raise.'
This is a typical hard-mode game, showing how the number of remaining solutions decreases with each guess, each of which is calculated according to the provided definition of 'best' (eliminates the greatest number of remaining solutions).
The code is currently configured for MI250X/gfx90a. At present, it is only tested with this hardware.
Michael E. Rowan – mrowan137 – [email protected].
This project is licensed under the MIT License – see LICENSE file for details.
© 2024 Michael E. Rowan. All rights reserved.
- Yy Wang: code-scrambler & co-conspirator
- Josh Wardle: original developer of Wordle
- String formatting function from Stack Overflow
- Wordle guesses and solutions from cfreshman's Gist