From a526735c5fd57640b619bcfb1c8ecd95101c5045 Mon Sep 17 00:00:00 2001 From: Max Regan Date: Fri, 4 Feb 2022 15:23:35 +0000 Subject: [PATCH] Update README.md --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46704ad..82bab72 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ # Wordle Solver -Cleanroom implementation of a solver for Wordle \ No newline at end of file +This is a toy project to implement a [Wordle](https://www.powerlanguage.co.uk/wordle/) solver. This project provides no packaging but has no dependencies on libraries that aren't builtin. The main function selects a random word, then simulates the game with the solver and prints the output. + +I didn't look at any other solutions before writing this, since that would ruin the fun. + +## Solver + +The solver is mostly brute-force. It takes every possible "guess" word from the dictionary (assumed to be in `/etc/share/dict/words`), and plays it to every possible "answer" in the dictionary, and determines the top moves. The ranking is based on a heuristic using the average number of remaining playable words, where fewer is better. + +Performance is reasonably optimized but the runtime of the overall algorithm is `O(n)^3`, where `n` is the size of the dictionary. Using 16 threads I was able to compute the first guess (the slowest) in about 6 hours using a dictionary of 3,000 5-letter words. The subsequent guesses are typically subsecond, and the first guess could be trivially cached since the initial board state is always the same. + +## Performance Notes + +I learned from this project that `deepcopy.copy` is outrageously slow, even for simple data classes. Initially, it dominated runtime when it was used to copy the board state for each evaluation. I replaced it with a hand-written copy, assigning immutable values and shallow copying dictionaries, and this allowed meeting sufficient performance for a toy.