wordl-solver 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +66 -0
- data/bin/wordl-solver +10 -2
- data/lib/data/allowed_guesses.txt +12972 -0
- data/lib/data/answers.txt +2315 -0
- data/lib/data/opening_scores.json +252 -0
- data/lib/wordl_solver/cli.rb +180 -0
- data/lib/wordl_solver/feedback.rb +58 -0
- data/lib/wordl_solver/filter.rb +66 -0
- data/lib/wordl_solver/game_state.rb +39 -0
- data/lib/wordl_solver/scorer.rb +37 -0
- data/lib/wordl_solver/version.rb +5 -0
- data/lib/wordl_solver/word_lists.rb +13 -0
- data/lib/wordl_solver.rb +28 -54
- metadata +30 -61
- data/.document +0 -5
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -113
- data/README.rdoc +0 -28
- data/Rakefile +0 -49
- data/VERSION +0 -1
- data/lib/5_words.csv +0 -5757
- data/lib/wordl_solver_interface.rb +0 -106
- data/wordl-solver.gemspec +0 -59
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 971e04860d52665cda7d60ed70620e482ab3e430257054d11bdc807308c12baa
|
|
4
|
+
data.tar.gz: 32a747b54c9765f467ee9577314baab53be899ffa1a0e395537ff933ed12d8b7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d79b870a00216e6e4ca66d2fefba913128e5374433e634c72e48265fcb011fd51aad985e3bfddee2691ff99cae1c078d5d8095667910f24c56350dd02784592a
|
|
7
|
+
data.tar.gz: 3d7c8713c93d569ae85dc378488a8b9594c5583e214ed08943f7218b9e7b7e9b4a4c66586c266ba5d8d76ceb12a6cc3e453f086f8b198ea709b5169bf1331e78
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0 — 2026-05-12
|
|
4
|
+
|
|
5
|
+
### Breaking changes
|
|
6
|
+
|
|
7
|
+
- **CLI input format** changed from per-position prompts to a single line per turn (`<word> <pattern>`). The old `sa`/`yr`/`so`-style prompting is gone.
|
|
8
|
+
- **Ruby API reshaped.** `WordlSolver.find_possible_words` is removed. The new API: `WordlSolver.score`, `WordlSolver::Filter.candidates`, `WordlSolver::Scorer.rank`, `WordlSolver::GameState`, `WordlSolver::Feedback`.
|
|
9
|
+
- **Word lists replaced** with the real Wordle answer (~2,315) and allowed-guess (~12,972) lists. The old `5_words.csv` is gone.
|
|
10
|
+
- **Ranking switched** from sum-of-letter-frequencies (and an ascending sort bug) to expected information gain (Shannon entropy).
|
|
11
|
+
- **Minimum Ruby** is now 3.0.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Duplicate-letter cases now scored correctly. In particular: yellow + grey of the same letter forces an exact count; two yellows of the same letter require ≥ 2 occurrences.
|
|
16
|
+
- Filter no longer carries state between games.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- `:undo`, `:restart`, `:quit`, `:help` commands.
|
|
21
|
+
- Precomputed top-50 opener entropy data (`lib/data/opening_scores.json`) so the first turn is instant.
|
|
22
|
+
- Property-based filter tests (200 random secrets × random guesses).
|
|
23
|
+
|
|
24
|
+
### Removed
|
|
25
|
+
|
|
26
|
+
- `juwelier` and `shoulda` dev dependencies.
|
|
27
|
+
- `README.rdoc` (superseded by `README.md`).
|
|
28
|
+
- Checked-in build artifact (`wordl-solver-1.4.2.gem`).
|
data/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# wordl-solver
|
|
2
|
+
|
|
3
|
+
A Ruby gem that solves Wordle puzzles by ranking each candidate guess by **expected information gain** — the same technique behind strong public Wordle solvers. Ships with the real Wordle answer and allowed-guess lists and a single-line CLI.
|
|
4
|
+
|
|
5
|
+
## How it ranks guesses
|
|
6
|
+
|
|
7
|
+
For each candidate guess, the solver simulates what feedback every still-possible answer would produce and computes the Shannon entropy of that distribution. A high-entropy guess splits the remaining answer set into many small buckets, telling you the most you can learn in one move. Higher score = better guess.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
gem install wordl-solver
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Use
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
wordl-solver
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
You enter one line per turn: the word you guessed and the color pattern you got. The pattern is 5 characters from `g` (green), `y` (yellow), `s` (grey). `b` and `.` are also accepted for grey.
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
> crane sygss
|
|
25
|
+
Turn 2 — 41 possible answers.
|
|
26
|
+
Possible answers:
|
|
27
|
+
poilu 3.92 bits
|
|
28
|
+
plumb 3.71 bits
|
|
29
|
+
High-info guesses:
|
|
30
|
+
pluot 4.21 bits (not a possible answer)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Commands
|
|
34
|
+
|
|
35
|
+
- `:undo` — remove the last turn.
|
|
36
|
+
- `:restart` — start over.
|
|
37
|
+
- `:quit` — exit.
|
|
38
|
+
- `:help` — print help.
|
|
39
|
+
|
|
40
|
+
### Flags
|
|
41
|
+
|
|
42
|
+
- `--top N` — show the top N suggestions (default 10).
|
|
43
|
+
|
|
44
|
+
## Going deeper
|
|
45
|
+
|
|
46
|
+
Two long-form docs explain how the gem works and why it's built the way it is. They're written to be readable on their own, not just as developer notes:
|
|
47
|
+
|
|
48
|
+
- [docs/ALGORITHM.md](docs/ALGORITHM.md) — the math. Walks through the Wordle scoring rule, the duplicate-letter filter algorithm, and the Shannon-entropy ranking from first principles, with worked examples. Useful if you want to understand *why* this approach works.
|
|
49
|
+
- [docs/DESIGN.md](docs/DESIGN.md) — the software design. Covers value objects, immutability, pure functions, separation of concerns, dependency injection in the CLI, and the test design philosophy. Useful if you want to learn Ruby design patterns from a small worked example.
|
|
50
|
+
|
|
51
|
+
## Development
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bundle install
|
|
55
|
+
bundle exec rake test
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
To regenerate the precomputed opening scores (only needed if word lists change):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
bundle exec rake compute_opening_scores
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT. See `LICENSE.txt`.
|
data/bin/wordl-solver
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
|
5
|
+
require "wordl_solver/cli"
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
WordlSolver::CLI.run(ARGV)
|
|
9
|
+
rescue ArgumentError => e
|
|
10
|
+
warn "wordl-solver: #{e.message}"
|
|
11
|
+
exit 2
|
|
12
|
+
end
|