From 70ead4b5209930b35f477e6ea7e3f0c5604aa6c5 Mon Sep 17 00:00:00 2001 From: Will Estes Date: Mon, 6 Jul 2026 07:56:56 -0400 Subject: [PATCH] initial commit --- .gitignore | 17 + Makefile | 4 + README.md | 89 + pyproject.toml | 21 + tests/test_cli.py | 84 + tests/test_game.py | 85 + tests/test_solver.py | 147 + tests/test_wager.py | 79 + wordle_solver/__init__.py | 1 + wordle_solver/__main__.py | 4 + wordle_solver/cli.py | 222 + wordle_solver/data/answers.txt | 2315 +++++++ wordle_solver/data/guesses.txt | 10657 +++++++++++++++++++++++++++++++ wordle_solver/game.py | 61 + wordle_solver/solver.py | 122 + wordle_solver/wager.py | 39 + wordle_solver/words.py | 27 + 17 files changed, 13974 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 pyproject.toml create mode 100644 tests/test_cli.py create mode 100644 tests/test_game.py create mode 100644 tests/test_solver.py create mode 100644 tests/test_wager.py create mode 100644 wordle_solver/__init__.py create mode 100644 wordle_solver/__main__.py create mode 100644 wordle_solver/cli.py create mode 100644 wordle_solver/data/answers.txt create mode 100644 wordle_solver/data/guesses.txt create mode 100644 wordle_solver/game.py create mode 100644 wordle_solver/solver.py create mode 100644 wordle_solver/wager.py create mode 100644 wordle_solver/words.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63268d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Virtual environment +.venv/ + +# Python bytecode +__pycache__/ +*.py[cod] + +# Packaging / build artifacts +*.egg-info/ +dist/ +build/ + +# Test cache +.pytest_cache/ + +# Local editor / tool settings (not for sharing) +.claude/settings.local.json diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8708ca3 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +.PHONY: check + +check: + .venv/bin/pytest tests/ -v diff --git a/README.md b/README.md new file mode 100644 index 0000000..e5d328d --- /dev/null +++ b/README.md @@ -0,0 +1,89 @@ +# Wordle Solver + +A hard-mode Wordle solving assistant. It narrows the candidate word list as you enter each guess and its result, and suggests the best next guesses using a letter-frequency heuristic. Includes a wager tracker for games played with per-letter betting rules. + +## Install + +### With pipx (recommended) + +[pipx](https://pipx.pypa.io) installs the `wordle` command globally in an isolated environment — no virtual environment to manage. + +```bash +pipx install . +``` + +To pick up code changes after editing the source: + +```bash +pipx reinstall wordle-solver +``` + +### With pip (development) + +Requires Python 3.9+. + +```bash +python3 -m venv .venv +source .venv/bin/activate +pip install -e . +``` + +This installs the `wordle` command into the virtual environment's `bin/`. + +### Options + +``` +wordle [--top N] [--position-weight F] [--presence-weight F] +``` + +| Flag | Default | Description | +|---|---|---| +| `--top N` | 10 | Number of suggestions to show after each guess | +| `--position-weight F` | 1.0 | Weight on per-position letter frequency in the heuristic | +| `--presence-weight F` | 1.0 | Weight on overall letter presence frequency in the heuristic | + +## Usage + +### Assisted mode (playing on an external Wordle board) + +After each guess you make on the Wordle site, enter the word and its color result as a single string of letter–digit pairs: + +``` +> c2r1a0n0e0 +``` + +Each digit encodes the tile color: + +| Digit | Meaning | +|---|---| +| `2` | Correct letter, correct spot (green / orange in colorblind mode) | +| `1` | Correct letter, wrong spot (yellow / blue in colorblind mode) | +| `0` | Letter not in the word (grey / black) | + +The solver prints how many candidates remain, lists them when 20 or fewer are left, and shows the top-ranked hard-mode-valid suggestions. + +### Practice mode + +`/practice` picks a secret word and lets you play through a full game. Type your guess as a plain word — no digits needed, the solver scores it for you. Hard mode is enforced: green letters must stay in their position, and all revealed letters must appear in every subsequent guess. + +## Commands + +| Command | Description | +|---|---| +| `help` | Print the help text | +| `reset` | Clear the solver state for a new puzzle (keeps wager session total) | +| `quit` | Exit | +| `/practice` | Start a practice game: solver picks a secret word, scores your guesses | +| `/round` | Start a new wager round: clears solver state and the round total, exits practice mode | +| `/price` | Reset per-letter wager prices to the defaults ($1 correct / $2 present / $3 absent) | +| `/price ` | Set custom per-letter prices, e.g. `/price 2 3 5` | + +## Wager tracking + +The solver tracks a running dollar cost for each guess based on its tile results. Default prices: + +- Correct (green): **$1** +- Present (yellow): **$2** +- Absent (grey): **$3** + +After each guess the solver prints the cost of that guess, the round total, and the session total. Use `/price` to match whatever betting rules your game uses. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..1f170ae --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,21 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "wordle-solver" +version = "0.1.0" +description = "Hard-mode Wordle solving assistant" +requires-python = ">=3.9" + +[project.scripts] +wordle = "wordle_solver.cli:run" + +[tool.setuptools.packages.find] +include = ["wordle_solver*"] + +[tool.setuptools.package-data] +wordle_solver = ["data/*.txt"] + +[project.optional-dependencies] +dev = ["pytest"] diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..ed7295d --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,84 @@ +import pytest + +from wordle_solver.game import Clue +from wordle_solver.cli import parse_line, hard_mode_violation + +G = Clue.GREEN +Y = Clue.YELLOW +B = Clue.GREY + + +class TestParseLine: + def test_digit_encoding(self): + guess, pattern = parse_line("c2r1a0n0e0") + assert guess == "crane" + assert pattern == (G, Y, B, B, B) + + def test_letter_encoding(self): + guess, pattern = parse_line("cGrYaBnBeB") + assert guess == "crane" + assert pattern == (G, Y, B, B, B) + + def test_spaces_stripped(self): + guess, pattern = parse_line("c 2 r 1 a 0 n 0 e 0") + assert guess == "crane" + assert pattern == (G, Y, B, B, B) + + def test_uppercase_letters_lowercased(self): + guess, _ = parse_line("C2R1A0N0E0") + assert guess == "crane" + + def test_all_green(self): + _, pattern = parse_line("c2r2a2n2e2") + assert pattern == (G, G, G, G, G) + + def test_wrong_length_raises(self): + with pytest.raises(ValueError): + parse_line("c2r1a0") # only 3 pairs + + def test_too_long_raises(self): + with pytest.raises(ValueError): + parse_line("c2r1a0n0e0x0") # 6 pairs + + def test_digit_in_letter_position_raises(self): + with pytest.raises(ValueError): + parse_line("12r1a0n0e0") # position 0 is '1', not a letter + + +class TestHardModeViolation: + def test_valid_guess_returns_none(self): + green = {0: "c", 1: "r"} + from collections import Counter + min_count = Counter({"a": 1}) + assert hard_mode_violation("crane", green, min_count) is None + + def test_wrong_green_position_detected(self): + green = {0: "c"} + from collections import Counter + result = hard_mode_violation("trace", green, Counter()) + assert result is not None + assert "1" in result # position 1 (1-indexed) + + def test_missing_required_letter_detected(self): + from collections import Counter + min_count = Counter({"r": 1}) + result = hard_mode_violation("piano", {}, min_count) + assert result is not None + assert "R" in result + + def test_missing_duplicate_letter_detected(self): + # Word needs two 'e's + from collections import Counter + min_count = Counter({"e": 2}) + result = hard_mode_violation("crane", {}, min_count) + assert result is not None # "crane" has only one 'e' + + def test_satisfies_duplicate_requirement(self): + from collections import Counter + min_count = Counter({"e": 2}) + result = hard_mode_violation("geese", {}, min_count) + assert result is None # "geese" has three 'e's — satisfies ≥2 + + def test_empty_constraints_always_none(self): + from collections import Counter + assert hard_mode_violation("crane", {}, Counter()) is None diff --git a/tests/test_game.py b/tests/test_game.py new file mode 100644 index 0000000..8950ce0 --- /dev/null +++ b/tests/test_game.py @@ -0,0 +1,85 @@ +import pytest + +from wordle_solver.game import Clue, score_guess, str_to_pattern, pattern_to_str, pattern_to_digits + +G = Clue.GREEN +Y = Clue.YELLOW +B = Clue.GREY + + +class TestScoreGuess: + def test_all_green(self): + assert score_guess("crane", "crane") == (G, G, G, G, G) + + def test_all_grey(self): + assert score_guess("brick", "those") == (B, B, B, B, B) + + def test_basic_yellow(self): + assert score_guess("trail", "blurt") == (Y, Y, B, B, Y) + + def test_basic_mixed(self): + assert score_guess("arise", "spare") == (Y, Y, B, Y, G) + + # Duplicate-letter cases — this is where the two-pass algorithm matters. + + def test_duplicate_in_guess_one_in_answer_first_gets_yellow(self): + # 'a' appears twice in "nasal" (pos 1, 3), once in "ultra" (pos 4). + # Neither is a green, so pass-2 left-to-right: pos 1 → yellow, pos 3 → grey. + assert score_guess("nasal", "ultra") == (B, Y, B, B, Y) + + def test_duplicate_in_guess_one_in_answer_green_takes_priority(self): + # "eerie" has 3 e's; "abcee" has 2. The last 'e' in the guess hits green + # at position 4; one remaining 'e' in the answer makes the first 'e' yellow; + # the middle 'e' has nothing left to match → grey. + assert score_guess("eerie", "abcee") == (Y, B, B, B, G) + + def test_duplicate_in_guess_both_in_answer(self): + # "sleep" has two 'e's; answer "geese" has three 'e's + # both guess 'e's should be coloured (green or yellow) + result = score_guess("sleep", "geese") + assert result[2] == G # 'e' at pos 2 matches answer pos 2 + assert result[3] in (G, Y) + + def test_duplicate_in_answer_guess_has_one(self): + # "abbey" has two 'b's; "bland" has one 'b' in the wrong position → yellow + assert score_guess("bland", "abbey") == (Y, B, Y, B, B) + + def test_guess_equals_answer_all_green(self): + for word in ("tales", "quick", "zzzzz"): + assert score_guess(word, word) == (G,) * 5 + + def test_yellow_not_double_counted(self): + # "added" vs "daddy": only two 'd's in answer, so not all three guess-d's get colour + result = score_guess("added", "daddy") + d_colours = [result[i] for i, c in enumerate("added") if c == "d"] + coloured = sum(1 for c in d_colours if c != B) + assert coloured <= 3 # answer has three 'd's at most + + +class TestStrToPattern: + def test_digit_encoding(self): + assert str_to_pattern("22110") == (G, G, Y, Y, B) + + def test_letter_encoding(self): + assert str_to_pattern("GGYYB") == (G, G, Y, Y, B) + + def test_lowercase_letter_encoding(self): + assert str_to_pattern("ggyyb") == (G, G, Y, Y, B) + + def test_mixed_encodings(self): + assert str_to_pattern("2G1Y0") == (G, G, Y, Y, B) + + def test_invalid_char_raises(self): + with pytest.raises(ValueError): + str_to_pattern("2210X") + + def test_dot_and_dash_are_grey(self): + assert str_to_pattern("..---") == (B,) * 5 + + +class TestPatternHelpers: + def test_pattern_to_str(self): + assert pattern_to_str((G, Y, B)) == "GYB" + + def test_pattern_to_digits(self): + assert pattern_to_digits((G, Y, B)) == "210" diff --git a/tests/test_solver.py b/tests/test_solver.py new file mode 100644 index 0000000..ba0eedc --- /dev/null +++ b/tests/test_solver.py @@ -0,0 +1,147 @@ +import pytest + +from wordle_solver.game import Clue, score_guess +from wordle_solver.solver import Solver, rank_guesses + +G = Clue.GREEN +Y = Clue.YELLOW +B = Clue.GREY + +ALL_GREEN = (G, G, G, G, G) + + +def make_solver(*extra): + """Solver with a small, controlled answer list.""" + answers = ["crane", "crave", "trace", "grace", "brace"] + return Solver(answers, list(extra)) + + +class TestSolverApply: + def test_all_candidates_initially(self): + s = make_solver() + assert set(s.candidates) == {"crane", "crave", "trace", "grace", "brace"} + + def test_apply_narrows_candidates(self): + s = make_solver() + # scoring "crane" against "crane" → all green → only "crane" remains + s.apply("crane", ALL_GREEN) + assert s.candidates == ["crane"] + + def test_apply_chain(self): + s = make_solver() + # first clue: 'c' correct, 'r' present, rest absent/wrong + pattern1 = score_guess("crane", "crave") + s.apply("crane", pattern1) + # 'crave' must still be a candidate; 'grace' and 'brace' may or may not be + assert "crave" in s.candidates + assert "crane" not in s.candidates + + def test_apply_empty_candidates_on_no_match(self): + s = make_solver() + # impossible pattern eliminates everything + s.apply("zzzzz", ALL_GREEN) + assert s.candidates == [] + + def test_reset_restores_all_candidates(self): + s = make_solver() + s.apply("crane", ALL_GREEN) + s.reset() + assert set(s.candidates) == {"crane", "crave", "trace", "grace", "brace"} + + def test_reset_clears_history(self): + s = make_solver() + s.apply("crane", ALL_GREEN) + s.reset() + assert s.history == [] + + def test_is_solved_after_all_green(self): + s = make_solver() + s.apply("crane", ALL_GREEN) + assert s.is_solved() + + def test_is_solved_false_initially(self): + assert not make_solver().is_solved() + + +class TestHardModeConstraints: + def test_green_positions_extracted(self): + s = make_solver() + s.apply("crane", (G, B, B, B, B)) # 'c' locked at position 0 + green, _ = s.hard_mode_constraints() + assert green == {0: "c"} + + def test_yellow_minimum_count(self): + s = make_solver() + s.apply("crane", (B, Y, B, B, B)) # 'r' must appear at least once + _, min_count = s.hard_mode_constraints() + assert min_count["r"] >= 1 + + def test_multiple_greens_accumulated(self): + s = make_solver() + s.apply("crane", (G, G, B, B, B)) + s.apply("crave", (G, G, B, G, B)) + green, _ = s.hard_mode_constraints() + assert green[0] == "c" + assert green[1] == "r" + assert green[3] == "v" + + def test_duplicate_yellow_counts_correctly(self): + s = make_solver() + # Two 'a's in a guess, both yellow → need at least 2 'a's + s.apply("llama", (B, B, Y, B, Y)) + _, min_count = s.hard_mode_constraints() + assert min_count["a"] >= 2 + + +class TestHardModePool: + def test_no_history_returns_all_words(self): + s = make_solver("extra1", "extra2") + pool = s.hard_mode_pool() + assert set(pool) == set(s.all_words) + + def test_green_constraint_filters_pool(self): + s = make_solver() + s.apply("crane", (G, B, B, B, B)) # first letter must be 'c' + pool = s.hard_mode_pool() + assert all(w[0] == "c" for w in pool) + + def test_yellow_constraint_filters_pool(self): + s = make_solver() + s.apply("crane", (B, Y, B, B, B)) # 'r' must be present + pool = s.hard_mode_pool() + assert all("r" in w for w in pool) + + def test_word_violating_green_excluded(self): + s = make_solver() + s.apply("crane", (G, B, B, B, B)) # 'c' at position 0 + pool = s.hard_mode_pool() + assert "trace" not in pool # starts with 't' + + +class TestRankGuesses: + def test_returns_at_most_top_n(self): + answers = ["crane", "crave", "trace", "grace", "brace"] + pool = answers[:] + results = rank_guesses(pool, answers, top_n=3) + assert len(results) <= 3 + + def test_possible_answers_tagged(self): + answers = ["crane", "crave"] + pool = answers + ["zzzzz"] + results = rank_guesses(pool, answers, top_n=10) + by_word = {w: is_ans for w, _, is_ans in results} + assert by_word["crane"] is True + assert by_word["crave"] is True + assert by_word["zzzzz"] is False + + def test_scores_descending(self): + answers = ["crane", "crave", "trace", "grace", "brace"] + results = rank_guesses(answers, answers, top_n=5) + scores = [s for _, s, _ in results] + assert scores == sorted(scores, reverse=True) + + def test_single_candidate_returned(self): + answers = ["crane"] + results = rank_guesses(answers, answers, top_n=5) + assert len(results) == 1 + assert results[0][0] == "crane" diff --git a/tests/test_wager.py b/tests/test_wager.py new file mode 100644 index 0000000..1eb4058 --- /dev/null +++ b/tests/test_wager.py @@ -0,0 +1,79 @@ +from wordle_solver.game import Clue +from wordle_solver.wager import Wager + +G = Clue.GREEN +Y = Clue.YELLOW +B = Clue.GREY + + +class TestWagerCost: + def test_all_correct_costs_one_each(self): + w = Wager() + assert w.cost_of((G, G, G, G, G)) == 5 + + def test_all_present_costs_two_each(self): + w = Wager() + assert w.cost_of((Y, Y, Y, Y, Y)) == 10 + + def test_all_absent_costs_three_each(self): + w = Wager() + assert w.cost_of((B, B, B, B, B)) == 15 + + def test_mixed_cost(self): + w = Wager() + assert w.cost_of((G, Y, B, G, B)) == 1 + 2 + 3 + 1 + 3 + + +class TestWagerAccumulation: + def test_add_accumulates_round_and_session(self): + w = Wager() + w.add((G, G, G, G, G)) # cost 5 + w.add((B, B, B, B, B)) # cost 15 + assert w.round_total == 20 + assert w.session_total == 20 + + def test_new_round_resets_round_total_only(self): + w = Wager() + w.add((G, G, G, G, G)) # cost 5 + w.new_round() + w.add((B, B, B, B, B)) # cost 15 in new round + assert w.round_total == 15 + assert w.session_total == 20 # unchanged across rounds + + def test_add_returns_cost_of_that_guess(self): + w = Wager() + cost = w.add((G, Y, B, G, B)) + assert cost == 1 + 2 + 3 + 1 + 3 + + def test_fresh_wager_starts_at_zero(self): + w = Wager() + assert w.round_total == 0 + assert w.session_total == 0 + + +class TestWagerPrices: + def test_set_prices_changes_cost(self): + w = Wager() + w.set_prices(10, 20, 30) + assert w.cost_of((G, Y, B)) == 60 + + def test_reset_via_set_prices_default(self): + w = Wager() + w.set_prices(10, 20, 30) + w.set_prices(1, 2, 3) + assert w.cost_of((G, Y, B)) == 6 + + def test_prices_str_contains_values(self): + w = Wager() + s = w.prices_str() + assert "$1" in s + assert "$2" in s + assert "$3" in s + + def test_prices_str_after_custom_prices(self): + w = Wager() + w.set_prices(5, 10, 15) + s = w.prices_str() + assert "$5" in s + assert "$10" in s + assert "$15" in s diff --git a/wordle_solver/__init__.py b/wordle_solver/__init__.py new file mode 100644 index 0000000..218b47a --- /dev/null +++ b/wordle_solver/__init__.py @@ -0,0 +1 @@ +"""Hard-mode Wordle solving assistant.""" diff --git a/wordle_solver/__main__.py b/wordle_solver/__main__.py new file mode 100644 index 0000000..2e933c9 --- /dev/null +++ b/wordle_solver/__main__.py @@ -0,0 +1,4 @@ +from .cli import run + +if __name__ == "__main__": + run() diff --git a/wordle_solver/cli.py b/wordle_solver/cli.py new file mode 100644 index 0000000..a1a9e65 --- /dev/null +++ b/wordle_solver/cli.py @@ -0,0 +1,222 @@ +"""Interactive REPL: enter each guess and its result, get ranked suggestions back.""" + +import argparse +import random +from collections import Counter + +from .game import Clue, score_guess, str_to_pattern +from .solver import MAX_GUESSES, WORD_LEN, Solver, rank_guesses +from .wager import Wager +from .words import load_answers, load_extra_guesses + +HELP_TEXT = """\ +Enter each letter followed by its result digit, e.g.: + c2r1a0n0e0 +Digits mean correct/present/absent, not literal color: + 2 = right letter, right spot (orange in colorblind mode) + 1 = right letter, wrong spot (blue in colorblind mode) + 0 = letter not in word (black in colorblind mode) + +In `/practice` mode, just type the guessed word — no digits needed, +the tool knows the secret and scores it for you. + +Commands: + help show this text + reset clear the solver (new puzzle, keeps wager totals) + quit exit + /practice pick a secret word and let you guess it (hard-mode enforced) + /round start a new wager round: clears solver + round total, exits practice + /price reset per-letter $ values to the default $1/$2/$3 + /price set per-letter $ values, e.g. `/price 1 2 3` +""" + + +def parse_line(line: str): + line = line.replace(" ", "") + if len(line) != 2 * WORD_LEN: + raise ValueError(f"expected {WORD_LEN} letter+digit pairs, e.g. `c2r1a0n0e0`") + guess = line[0::2].lower() + result = line[1::2] + if not guess.isalpha(): + raise ValueError(f"expected {WORD_LEN} letter+digit pairs, e.g. `c2r1a0n0e0`") + return guess, str_to_pattern(result) + + +def hard_mode_violation(guess: str, green: dict, min_count: Counter): + """Return a human-readable reason `guess` breaks hard mode, or None if it's legal.""" + for i, ch in green.items(): + if guess[i] != ch: + return f"position {i + 1} must be '{ch.upper()}'" + counts = Counter(guess) + for ch, need in min_count.items(): + if counts[ch] < need: + return f"must include letter '{ch.upper()}' (need at least {need})" + return None + + +def format_result(guess: str, pattern) -> str: + labels = {Clue.GREEN: "correct", Clue.YELLOW: "present", Clue.GREY: "absent"} + return " ".join(f"{ch.upper()}:{labels[clue]}" for ch, clue in zip(guess, pattern)) + + +def handle_slash_command(line: str, solver: Solver, wager: Wager, state: dict, answers: list, opts) -> None: + parts = line.split() + cmd = parts[0].lower() + + if cmd == "/practice": + solver.reset() + wager.new_round() + state["secret"] = random.choice(answers) + state["guesses_made"] = 0 + print(f"Practice round started — I picked a secret word. You have {MAX_GUESSES} guesses.") + print(f"Just type the {WORD_LEN}-letter word you're guessing (hard mode enforced).") + print_suggestions(solver, opts.top, opts.position_weight, opts.presence_weight) + return + + if cmd == "/round": + solver.reset() + wager.new_round() + state["secret"] = None + state["guesses_made"] = 0 + print(f"New round. Prices: {wager.prices_str()} | session total: ${wager.session_total}") + print_suggestions(solver, opts.top, opts.position_weight, opts.presence_weight) + return + + if cmd == "/price": + args = parts[1:] + if not args: + wager.set_prices(1, 2, 3) + print(f"Prices reset to default. {wager.prices_str()}") + elif len(args) == 3 and all(a.lstrip("-").isdigit() for a in args): + wager.set_prices(*(int(a) for a in args)) + print(f"Prices updated. {wager.prices_str()}") + else: + print("Usage: `/price` (reset to $1/$2/$3) or `/price `") + return + print(f"Round total so far: ${wager.round_total} | session total: ${wager.session_total}") + return + + print(f"Unknown command: {cmd} (try 'help')") + + +def print_suggestions(solver: Solver, top_n: int, position_weight: float, presence_weight: float): + n_remaining = len(solver.candidates) + print(f"\n{n_remaining} possible answer(s) remain.") + if n_remaining <= 20: + print(" " + ", ".join(sorted(solver.candidates))) + + pool = solver.hard_mode_pool() + suggestions = rank_guesses(pool, solver.candidates, top_n=top_n, + position_weight=position_weight, presence_weight=presence_weight) + if not suggestions: + print("No hard-mode-legal words left in the word list (check your entered results).") + return + + print(f"\nTop {len(suggestions)} suggestion(s) (hard-mode legal):") + for rank, (word, score, is_answer) in enumerate(suggestions, start=1): + tag = "possible answer" if is_answer else "scout" + print(f" {rank:>2}. {word:<6} (heuristic {score:.3f}, {tag})") + + +def run(args=None): + parser = argparse.ArgumentParser(description="Hard-mode Wordle solving assistant.") + parser.add_argument("--top", type=int, default=10, help="number of suggestions to show (default: 10)") + parser.add_argument("--position-weight", type=float, default=1.0, + help="weight on per-position letter frequency (default: 1.0)") + parser.add_argument("--presence-weight", type=float, default=1.0, + help="weight on overall letter presence frequency (default: 1.0)") + opts = parser.parse_args(args) + + answers = load_answers() + extra_guesses = load_extra_guesses() + solver = Solver(answers, extra_guesses) + wager = Wager() + state = {"secret": None, "guesses_made": 0} + + print("Wordle hard-mode assistant. Type 'help' for instructions.") + print(f"Wager prices: {wager.prices_str()}") + print_suggestions(solver, opts.top, opts.position_weight, opts.presence_weight) + + while True: + try: + line = input("\n> ").strip() + except (EOFError, KeyboardInterrupt): + print() + break + + if not line: + continue + if line.lower() in ("quit", "exit", "q"): + break + if line.lower() == "help": + print(HELP_TEXT) + continue + if line.lower() == "reset": + solver.reset() + state["secret"] = None + state["guesses_made"] = 0 + print("Reset.") + print_suggestions(solver, opts.top, opts.position_weight, opts.presence_weight) + continue + if line.startswith("/"): + handle_slash_command(line, solver, wager, state, answers, opts) + continue + + if state["secret"] is not None: + guess = line.lower() + if len(guess) != WORD_LEN or not guess.isalpha(): + print(f"Guess must be a {WORD_LEN}-letter word.") + continue + if guess not in solver.all_words: + print("Not in word list.") + continue + green, min_count = solver.hard_mode_constraints() + violation = hard_mode_violation(guess, green, min_count) + if violation: + print(f"Hard mode violation: {violation}") + continue + + pattern = score_guess(guess, state["secret"]) + solver.apply(guess, pattern) + state["guesses_made"] += 1 + cost = wager.add(pattern) + print(format_result(guess, pattern)) + print(f"Cost: ${cost} | round total: ${wager.round_total} | session total: ${wager.session_total}") + + if pattern == (Clue.GREEN,) * WORD_LEN: + print(f"Solved in {state['guesses_made']} guess(es)! The word was {guess.upper()} \U0001F389") + print("'/practice' for another word, '/round' to switch back to manual mode.") + state["secret"] = None + continue + if state["guesses_made"] >= MAX_GUESSES: + print(f"Out of guesses. The word was {state['secret'].upper()}.") + state["secret"] = None + continue + + print_suggestions(solver, opts.top, opts.position_weight, opts.presence_weight) + continue + + try: + guess, pattern = parse_line(line) + except ValueError as e: + print(f"Couldn't parse that: {e}") + continue + + solver.apply(guess, pattern) + cost = wager.add(pattern) + print(f"Cost: ${cost} | round total: ${wager.round_total} | session total: ${wager.session_total}") + + if pattern == (Clue.GREEN,) * WORD_LEN: + print(f"Solved: {guess.upper()} \U0001F389 ('/round' to start a new round)") + continue + + if not solver.candidates: + print("No remaining candidates match all the results entered so far — " + "double check the guess/result pairs, or 'reset' to start over.") + continue + + print_suggestions(solver, opts.top, opts.position_weight, opts.presence_weight) + + +if __name__ == "__main__": + run() diff --git a/wordle_solver/data/answers.txt b/wordle_solver/data/answers.txt new file mode 100644 index 0000000..4dd830e --- /dev/null +++ b/wordle_solver/data/answers.txt @@ -0,0 +1,2315 @@ +aback +abase +abate +abbey +abbot +abhor +abide +abled +abode +abort +about +above +abuse +abyss +acorn +acrid +actor +acute +adage +adapt +adept +admin +admit +adobe +adopt +adore +adorn +adult +affix +afire +afoot +afoul +after +again +agape +agate +agent +agile +aging +aglow +agony +agora +agree +ahead +aider +aisle +alarm +album +alert +algae +alibi +alien +align +alike +alive +allay +alley +allot +allow +alloy +aloft +alone +along +aloof +aloud +alpha +altar +alter +amass +amaze +amber +amble +amend +amiss +amity +among +ample +amply +amuse +angel +anger +angle +angry +angst +anime +ankle +annex +annoy +annul +anode +antic +anvil +aorta +apart +aphid +aping +apnea +apple +apply +apron +aptly +arbor +ardor +arena +argue +arise +armor +aroma +arose +array +arrow +arson +artsy +ascot +ashen +aside +askew +assay +asset +atoll +atone +attic +audio +audit +augur +aunty +avail +avert +avian +avoid +await +awake +award +aware +awash +awful +awoke +axial +axiom +axion +azure +bacon +badge +badly +bagel +baggy +baker +baler +balmy +banal +banjo +barge +baron +basal +basic +basil +basin +basis +baste +batch +bathe +baton +batty +bawdy +bayou +beach +beady +beard +beast +beech +beefy +befit +began +begat +beget +begin +begun +being +belch +belie +belle +belly +below +bench +beret +berry +berth +beset +betel +bevel +bezel +bible +bicep +biddy +bigot +bilge +billy +binge +bingo +biome +birch +birth +bison +bitty +black +blade +blame +bland +blank +blare +blast +blaze +bleak +bleat +bleed +bleep +blend +bless +blimp +blind +blink +bliss +blitz +bloat +block +bloke +blond +blood +bloom +blown +bluer +bluff +blunt +blurb +blurt +blush +board +boast +bobby +boney +bongo +bonus +booby +boost +booth +booty +booze +boozy +borax +borne +bosom +bossy +botch +bough +boule +bound +bowel +boxer +brace +braid +brain +brake +brand +brash +brass +brave +bravo +brawl +brawn +bread +break +breed +briar +bribe +brick +bride +brief +brine +bring +brink +briny +brisk +broad +broil +broke +brood +brook +broom +broth +brown +brunt +brush +brute +buddy +budge +buggy +bugle +build +built +bulge +bulky +bully +bunch +bunny +burly +burnt +burst +bused +bushy +butch +butte +buxom +buyer +bylaw +cabal +cabby +cabin +cable +cacao +cache +cacti +caddy +cadet +cagey +cairn +camel +cameo +canal +candy +canny +canoe +canon +caper +caput +carat +cargo +carol +carry +carve +caste +catch +cater +catty +caulk +cause +cavil +cease +cedar +cello +chafe +chaff +chain +chair +chalk +champ +chant +chaos +chard +charm +chart +chase +chasm +cheap +cheat +check +cheek +cheer +chess +chest +chick +chide +chief +child +chili +chill +chime +china +chirp +chock +choir +choke +chord +chore +chose +chuck +chump +chunk +churn +chute +cider +cigar +cinch +circa +civic +civil +clack +claim +clamp +clang +clank +clash +clasp +class +clean +clear +cleat +cleft +clerk +click +cliff +climb +cling +clink +cloak +clock +clone +close +cloth +cloud +clout +clove +clown +cluck +clued +clump +clung +coach +coast +cobra +cocoa +colon +color +comet +comfy +comic +comma +conch +condo +conic +copse +coral +corer +corny +couch +cough +could +count +coupe +court +coven +cover +covet +covey +cower +coyly +crack +craft +cramp +crane +crank +crash +crass +crate +crave +crawl +craze +crazy +creak +cream +credo +creed +creek +creep +creme +crepe +crept +cress +crest +crick +cried +crier +crime +crimp +crisp +croak +crock +crone +crony +crook +cross +croup +crowd +crown +crude +cruel +crumb +crump +crush +crust +crypt +cubic +cumin +curio +curly +curry +curse +curve +curvy +cutie +cyber +cycle +cynic +daddy +daily +dairy +daisy +dally +dance +dandy +datum +daunt +dealt +death +debar +debit +debug +debut +decal +decay +decor +decoy +decry +defer +deign +deity +delay +delta +delve +demon +demur +denim +dense +depot +depth +derby +deter +detox +deuce +devil +diary +dicey +digit +dilly +dimly +diner +dingo +dingy +diode +dirge +dirty +disco +ditch +ditto +ditty +diver +dizzy +dodge +dodgy +dogma +doing +dolly +donor +donut +dopey +doubt +dough +dowdy +dowel +downy +dowry +dozen +draft +drain +drake +drama +drank +drape +drawl +drawn +dread +dream +dress +dried +drier +drift +drill +drink +drive +droit +droll +drone +drool +droop +dross +drove +drown +druid +drunk +dryer +dryly +duchy +dully +dummy +dumpy +dunce +dusky +dusty +dutch +duvet +dwarf +dwell +dwelt +dying +eager +eagle +early +earth +easel +eaten +eater +ebony +eclat +edict +edify +eerie +egret +eight +eject +eking +elate +elbow +elder +elect +elegy +elfin +elide +elite +elope +elude +email +embed +ember +emcee +empty +enact +endow +enema +enemy +enjoy +ennui +ensue +enter +entry +envoy +epoch +epoxy +equal +equip +erase +erect +erode +error +erupt +essay +ester +ether +ethic +ethos +etude +evade +event +every +evict +evoke +exact +exalt +excel +exert +exile +exist +expel +extol +extra +exult +eying +fable +facet +faint +fairy +faith +false +fancy +fanny +farce +fatal +fatty +fault +fauna +favor +feast +fecal +feign +fella +felon +femme +femur +fence +feral +ferry +fetal +fetch +fetid +fetus +fever +fewer +fiber +fibre +ficus +field +fiend +fiery +fifth +fifty +fight +filer +filet +filly +filmy +filth +final +finch +finer +first +fishy +fixer +fizzy +fjord +flack +flail +flair +flake +flaky +flame +flank +flare +flash +flask +fleck +fleet +flesh +flick +flier +fling +flint +flirt +float +flock +flood +floor +flora +floss +flour +flout +flown +fluff +fluid +fluke +flume +flung +flunk +flush +flute +flyer +foamy +focal +focus +foggy +foist +folio +folly +foray +force +forge +forgo +forte +forth +forty +forum +found +foyer +frail +frame +frank +fraud +freak +freed +freer +fresh +friar +fried +frill +frisk +fritz +frock +frond +front +frost +froth +frown +froze +fruit +fudge +fugue +fully +fungi +funky +funny +furor +furry +fussy +fuzzy +gaffe +gaily +gamer +gamma +gamut +gassy +gaudy +gauge +gaunt +gauze +gavel +gawky +gayer +gayly +gazer +gecko +geeky +geese +genie +genre +ghost +ghoul +giant +giddy +gipsy +girly +girth +given +giver +glade +gland +glare +glass +glaze +gleam +glean +glide +glint +gloat +globe +gloom +glory +gloss +glove +glyph +gnash +gnome +godly +going +golem +golly +gonad +goner +goody +gooey +goofy +goose +gorge +gouge +gourd +grace +grade +graft +grail +grain +grand +grant +grape +graph +grasp +grass +grate +grave +gravy +graze +great +greed +green +greet +grief +grill +grime +grimy +grind +gripe +groan +groin +groom +grope +gross +group +grout +grove +growl +grown +gruel +gruff +grunt +guard +guava +guess +guest +guide +guild +guile +guilt +guise +gulch +gully +gumbo +gummy +guppy +gusto +gusty +gypsy +habit +hairy +halve +handy +happy +hardy +harem +harpy +harry +harsh +haste +hasty +hatch +hater +haunt +haute +haven +havoc +hazel +heady +heard +heart +heath +heave +heavy +hedge +hefty +heist +helix +hello +hence +heron +hilly +hinge +hippo +hippy +hitch +hoard +hobby +hoist +holly +homer +honey +honor +horde +horny +horse +hotel +hotly +hound +house +hovel +hover +howdy +human +humid +humor +humph +humus +hunch +hunky +hurry +husky +hussy +hutch +hydro +hyena +hymen +hyper +icily +icing +ideal +idiom +idiot +idler +idyll +igloo +iliac +image +imbue +impel +imply +inane +inbox +incur +index +inept +inert +infer +ingot +inlay +inlet +inner +input +inter +intro +ionic +irate +irony +islet +issue +itchy +ivory +jaunt +jazzy +jelly +jerky +jetty +jewel +jiffy +joint +joist +joker +jolly +joust +judge +juice +juicy +jumbo +jumpy +junta +junto +juror +kappa +karma +kayak +kebab +khaki +kinky +kiosk +kitty +knack +knave +knead +kneed +kneel +knelt +knife +knock +knoll +known +koala +krill +label +labor +laden +ladle +lager +lance +lanky +lapel +lapse +large +larva +lasso +latch +later +lathe +latte +laugh +layer +leach +leafy +leaky +leant +leapt +learn +lease +leash +least +leave +ledge +leech +leery +lefty +legal +leggy +lemon +lemur +leper +level +lever +libel +liege +light +liken +lilac +limbo +limit +linen +liner +lingo +lipid +lithe +liver +livid +llama +loamy +loath +lobby +local +locus +lodge +lofty +logic +login +loopy +loose +lorry +loser +louse +lousy +lover +lower +lowly +loyal +lucid +lucky +lumen +lumpy +lunar +lunch +lunge +lupus +lurch +lurid +lusty +lying +lymph +lynch +lyric +macaw +macho +macro +madam +madly +mafia +magic +magma +maize +major +maker +mambo +mamma +mammy +manga +mange +mango +mangy +mania +manic +manly +manor +maple +march +marry +marsh +mason +masse +match +matey +mauve +maxim +maybe +mayor +mealy +meant +meaty +mecca +medal +media +medic +melee +melon +mercy +merge +merit +merry +metal +meter +metro +micro +midge +midst +might +milky +mimic +mince +miner +minim +minor +minty +minus +mirth +miser +missy +mocha +modal +model +modem +mogul +moist +molar +moldy +money +month +moody +moose +moral +moron +morph +mossy +motel +motif +motor +motto +moult +mound +mount +mourn +mouse +mouth +mover +movie +mower +mucky +mucus +muddy +mulch +mummy +munch +mural +murky +mushy +music +musky +musty +myrrh +nadir +naive +nanny +nasal +nasty +natal +naval +navel +needy +neigh +nerdy +nerve +never +newer +newly +nicer +niche +niece +night +ninja +ninny +ninth +noble +nobly +noise +noisy +nomad +noose +north +nosey +notch +novel +nudge +nurse +nutty +nylon +nymph +oaken +obese +occur +ocean +octal +octet +odder +oddly +offal +offer +often +olden +older +olive +ombre +omega +onion +onset +opera +opine +opium +optic +orbit +order +organ +other +otter +ought +ounce +outdo +outer +outgo +ovary +ovate +overt +ovine +ovoid +owing +owner +oxide +ozone +paddy +pagan +paint +paler +palsy +panel +panic +pansy +papal +paper +parer +parka +parry +parse +party +pasta +paste +pasty +patch +patio +patsy +patty +pause +payee +payer +peace +peach +pearl +pecan +pedal +penal +pence +penne +penny +perch +peril +perky +pesky +pesto +petal +petty +phase +phone +phony +photo +piano +picky +piece +piety +piggy +pilot +pinch +piney +pinky +pinto +piper +pique +pitch +pithy +pivot +pixel +pixie +pizza +place +plaid +plain +plait +plane +plank +plant +plate +plaza +plead +pleat +plied +plier +pluck +plumb +plume +plump +plunk +plush +poesy +point +poise +poker +polar +polka +polyp +pooch +poppy +porch +poser +posit +posse +pouch +pound +pouty +power +prank +prawn +preen +press +price +prick +pride +pried +prime +primo +print +prior +prism +privy +prize +probe +prone +prong +proof +prose +proud +prove +prowl +proxy +prude +prune +psalm +pubic +pudgy +puffy +pulpy +pulse +punch +pupal +pupil +puppy +puree +purer +purge +purse +pushy +putty +pygmy +quack +quail +quake +qualm +quark +quart +quash +quasi +queen +queer +quell +query +quest +queue +quick +quiet +quill +quilt +quirk +quite +quota +quote +quoth +rabbi +rabid +racer +radar +radii +radio +rainy +raise +rajah +rally +ralph +ramen +ranch +randy +range +rapid +rarer +raspy +ratio +ratty +raven +rayon +razor +reach +react +ready +realm +rearm +rebar +rebel +rebus +rebut +recap +recur +recut +reedy +refer +refit +regal +rehab +reign +relax +relay +relic +remit +renal +renew +repay +repel +reply +rerun +reset +resin +retch +retro +retry +reuse +revel +revue +rhino +rhyme +rider +ridge +rifle +right +rigid +rigor +rinse +ripen +riper +risen +riser +risky +rival +river +rivet +roach +roast +robin +robot +rocky +rodeo +roger +rogue +roomy +roost +rotor +rouge +rough +round +rouse +route +rover +rowdy +rower +royal +ruddy +ruder +rugby +ruler +rumba +rumor +rupee +rural +rusty +sadly +safer +saint +salad +sally +salon +salsa +salty +salve +salvo +sandy +saner +sappy +sassy +satin +satyr +sauce +saucy +sauna +saute +savor +savoy +savvy +scald +scale +scalp +scaly +scamp +scant +scare +scarf +scary +scene +scent +scion +scoff +scold +scone +scoop +scope +score +scorn +scour +scout +scowl +scram +scrap +scree +screw +scrub +scrum +scuba +sedan +seedy +segue +seize +semen +sense +sepia +serif +serum +serve +setup +seven +sever +sewer +shack +shade +shady +shaft +shake +shaky +shale +shall +shalt +shame +shank +shape +shard +share +shark +sharp +shave +shawl +shear +sheen +sheep +sheer +sheet +sheik +shelf +shell +shied +shift +shine +shiny +shire +shirk +shirt +shoal +shock +shone +shook +shoot +shore +shorn +short +shout +shove +shown +showy +shrew +shrub +shrug +shuck +shunt +shush +shyly +siege +sieve +sight +sigma +silky +silly +since +sinew +singe +siren +sissy +sixth +sixty +skate +skier +skiff +skill +skimp +skirt +skulk +skull +skunk +slack +slain +slang +slant +slash +slate +slave +sleek +sleep +sleet +slept +slice +slick +slide +slime +slimy +sling +slink +sloop +slope +slosh +sloth +slump +slung +slunk +slurp +slush +slyly +smack +small +smart +smash +smear +smell +smelt +smile +smirk +smite +smith +smock +smoke +smoky +smote +snack +snail +snake +snaky +snare +snarl +sneak +sneer +snide +sniff +snipe +snoop +snore +snort +snout +snowy +snuck +snuff +soapy +sober +soggy +solar +solid +solve +sonar +sonic +sooth +sooty +sorry +sound +south +sower +space +spade +spank +spare +spark +spasm +spawn +speak +spear +speck +speed +spell +spelt +spend +spent +sperm +spice +spicy +spied +spiel +spike +spiky +spill +spilt +spine +spiny +spire +spite +splat +split +spoil +spoke +spoof +spook +spool +spoon +spore +sport +spout +spray +spree +sprig +spunk +spurn +spurt +squad +squat +squib +stack +staff +stage +staid +stain +stair +stake +stale +stalk +stall +stamp +stand +stank +stare +stark +start +stash +state +stave +stead +steak +steal +steam +steed +steel +steep +steer +stein +stern +stick +stiff +still +stilt +sting +stink +stint +stock +stoic +stoke +stole +stomp +stone +stony +stood +stool +stoop +store +stork +storm +story +stout +stove +strap +straw +stray +strip +strut +stuck +study +stuff +stump +stung +stunk +stunt +style +suave +sugar +suing +suite +sulky +sully +sumac +sunny +super +surer +surge +surly +sushi +swami +swamp +swarm +swash +swath +swear +sweat +sweep +sweet +swell +swept +swift +swill +swine +swing +swirl +swish +swoon +swoop +sword +swore +sworn +swung +synod +syrup +tabby +table +taboo +tacit +tacky +taffy +taint +taken +taker +tally +talon +tamer +tango +tangy +taper +tapir +tardy +tarot +taste +tasty +tatty +taunt +tawny +teach +teary +tease +teddy +teeth +tempo +tenet +tenor +tense +tenth +tepee +tepid +terra +terse +testy +thank +theft +their +theme +there +these +theta +thick +thief +thigh +thing +think +third +thong +thorn +those +three +threw +throb +throw +thrum +thumb +thump +thyme +tiara +tibia +tidal +tiger +tight +tilde +timer +timid +tipsy +titan +tithe +title +toast +today +toddy +token +tonal +tonga +tonic +tooth +topaz +topic +torch +torso +torus +total +totem +touch +tough +towel +tower +toxic +toxin +trace +track +tract +trade +trail +train +trait +tramp +trash +trawl +tread +treat +trend +triad +trial +tribe +trice +trick +tried +tripe +trite +troll +troop +trope +trout +trove +truce +truck +truer +truly +trump +trunk +truss +trust +truth +tryst +tubal +tuber +tulip +tulle +tumor +tunic +turbo +tutor +twang +tweak +tweed +tweet +twice +twine +twirl +twist +twixt +tying +udder +ulcer +ultra +umbra +uncle +uncut +under +undid +undue +unfed +unfit +unify +union +unite +unity +unlit +unmet +unset +untie +until +unwed +unzip +upper +upset +urban +urine +usage +usher +using +usual +usurp +utile +utter +vague +valet +valid +valor +value +valve +vapid +vapor +vault +vaunt +vegan +venom +venue +verge +verse +verso +verve +vicar +video +vigil +vigor +villa +vinyl +viola +viper +viral +virus +visit +visor +vista +vital +vivid +vixen +vocal +vodka +vogue +voice +voila +vomit +voter +vouch +vowel +vying +wacky +wafer +wager +wagon +waist +waive +waltz +warty +waste +watch +water +waver +waxen +weary +weave +wedge +weedy +weigh +weird +welch +welsh +wench +whack +whale +wharf +wheat +wheel +whelp +where +which +whiff +while +whine +whiny +whirl +whisk +white +whole +whoop +whose +widen +wider +widow +width +wield +wight +willy +wimpy +wince +winch +windy +wiser +wispy +witch +witty +woken +woman +women +woody +wooer +wooly +woozy +wordy +world +worry +worse +worst +worth +would +wound +woven +wrack +wrath +wreak +wreck +wrest +wring +wrist +write +wrong +wrote +wrung +wryly +yacht +yearn +yeast +yield +young +youth +zebra +zesty +zonal diff --git a/wordle_solver/data/guesses.txt b/wordle_solver/data/guesses.txt new file mode 100644 index 0000000..cc443a0 --- /dev/null +++ b/wordle_solver/data/guesses.txt @@ -0,0 +1,10657 @@ +aahed +aalii +aargh +aarti +abaca +abaci +abacs +abaft +abaka +abamp +aband +abash +abask +abaya +abbas +abbed +abbes +abcee +abeam +abear +abele +abers +abets +abies +abler +ables +ablet +ablow +abmho +abohm +aboil +aboma +aboon +abord +abore +abram +abray +abrim +abrin +abris +absey +absit +abuna +abune +abuts +abuzz +abyes +abysm +acais +acari +accas +accoy +acerb +acers +aceta +achar +ached +aches +achoo +acids +acidy +acing +acini +ackee +acker +acmes +acmic +acned +acnes +acock +acold +acred +acres +acros +acted +actin +acton +acyls +adaws +adays +adbot +addax +added +adder +addio +addle +adeem +adhan +adieu +adios +adits +adman +admen +admix +adobo +adown +adoze +adrad +adred +adsum +aduki +adunc +adust +advew +adyta +adzed +adzes +aecia +aedes +aegis +aeons +aerie +aeros +aesir +afald +afara +afars +afear +aflaj +afore +afrit +afros +agama +agami +agars +agast +agave +agaze +agene +agers +agger +aggie +aggri +aggro +aggry +aghas +agila +agios +agism +agist +agita +aglee +aglet +agley +agloo +aglus +agmas +agoge +agone +agons +agood +agria +agrin +agros +agued +agues +aguna +aguti +aheap +ahent +ahigh +ahind +ahing +ahint +ahold +ahull +ahuru +aidas +aided +aides +aidoi +aidos +aiery +aigas +aight +ailed +aimed +aimer +ainee +ainga +aioli +aired +airer +airns +airth +airts +aitch +aitus +aiver +aiyee +aizle +ajies +ajiva +ajuga +ajwan +akees +akela +akene +aking +akita +akkas +alaap +alack +alamo +aland +alane +alang +alans +alant +alapa +alaps +alary +alate +alays +albas +albee +alcid +alcos +aldea +alder +aldol +aleck +alecs +alefs +aleft +aleph +alews +aleye +alfas +algal +algas +algid +algin +algor +algum +alias +alifs +aline +alist +aliya +alkie +alkos +alkyd +alkyl +allee +allel +allis +allod +allyl +almah +almas +almeh +almes +almud +almug +alods +aloed +aloes +aloha +aloin +aloos +alowe +altho +altos +alula +alums +alure +alvar +alway +amahs +amain +amate +amaut +amban +ambit +ambos +ambry +ameba +ameer +amene +amens +ament +amias +amice +amici +amide +amido +amids +amies +amiga +amigo +amine +amino +amins +amirs +amlas +amman +ammon +ammos +amnia +amnic +amnio +amoks +amole +amort +amour +amove +amowt +amped +ampul +amrit +amuck +amyls +anana +anata +ancho +ancle +ancon +andro +anear +anele +anent +angas +anglo +anigh +anile +anils +anima +animi +anion +anise +anker +ankhs +ankus +anlas +annal +annas +annat +anoas +anole +anomy +ansae +antae +antar +antas +anted +antes +antis +antra +antre +antsy +anura +anyon +apace +apage +apaid +apayd +apays +apeak +apeek +apers +apert +apery +apgar +aphis +apian +apiol +apish +apism +apode +apods +apoop +aport +appal +appay +appel +appro +appui +appuy +apres +apses +apsis +apsos +apted +apter +aquae +aquas +araba +araks +arame +arars +arbas +arced +archi +arcos +arcus +ardeb +ardri +aread +areae +areal +arear +areas +areca +aredd +arede +arefy +areic +arene +arepa +arere +arete +arets +arett +argal +argan +argil +argle +argol +argon +argot +argus +arhat +arias +ariel +ariki +arils +ariot +arish +arked +arled +arles +armed +armer +armet +armil +arnas +arnut +aroba +aroha +aroid +arpas +arpen +arrah +arras +arret +arris +arroz +arsed +arses +arsey +arsis +artal +artel +artic +artis +aruhe +arums +arval +arvee +arvos +aryls +asana +ascon +ascus +asdic +ashed +ashes +ashet +asked +asker +askoi +askos +aspen +asper +aspic +aspie +aspis +aspro +assai +assam +asses +assez +assot +aster +astir +astun +asura +asway +aswim +asyla +ataps +ataxy +atigi +atilt +atimy +atlas +atman +atmas +atmos +atocs +atoke +atoks +atoms +atomy +atony +atopy +atria +atrip +attap +attar +atuas +audad +auger +aught +aulas +aulic +auloi +aulos +aumil +aunes +aunts +aurae +aural +aurar +auras +aurei +aures +auric +auris +aurum +autos +auxin +avale +avant +avast +avels +avens +avers +avgas +avine +avion +avise +aviso +avize +avows +avyze +awarn +awato +awave +aways +awdls +aweel +aweto +awing +awmry +awned +awner +awols +awork +axels +axile +axils +axing +axite +axled +axles +axman +axmen +axoid +axone +axons +ayahs +ayaya +ayelp +aygre +ayins +ayont +ayres +ayrie +azans +azide +azido +azine +azlon +azoic +azole +azons +azote +azoth +azuki +azurn +azury +azygy +azyme +azyms +baaed +baals +babas +babel +babes +babka +baboo +babul +babus +bacca +bacco +baccy +bacha +bachs +backs +baddy +baels +baffs +baffy +bafts +baghs +bagie +bahts +bahus +bahut +bails +bairn +baisa +baith +baits +baiza +baize +bajan +bajra +bajri +bajus +baked +baken +bakes +bakra +balas +balds +baldy +baled +bales +balks +balky +balls +bally +balms +baloo +balsa +balti +balun +balus +bambi +banak +banco +bancs +banda +bandh +bands +bandy +baned +banes +bangs +bania +banks +banns +bants +bantu +banty +banya +bapus +barbe +barbs +barby +barca +barde +bardo +bards +bardy +bared +barer +bares +barfi +barfs +baric +barks +barky +barms +barmy +barns +barny +barps +barra +barre +barro +barry +barye +basan +based +basen +baser +bases +basho +basij +basks +bason +basse +bassi +basso +bassy +basta +basti +basto +basts +bated +bates +baths +batik +batta +batts +battu +bauds +bauks +baulk +baurs +bavin +bawds +bawks +bawls +bawns +bawrs +bawty +bayed +bayer +bayes +bayle +bayts +bazar +bazoo +beads +beaks +beaky +beals +beams +beamy +beano +beans +beany +beare +bears +beath +beats +beaty +beaus +beaut +beaux +bebop +becap +becke +becks +bedad +bedel +bedes +bedew +bedim +bedye +beedi +beefs +beeps +beers +beery +beets +befog +begad +begar +begem +begot +begum +beige +beigy +beins +bekah +belah +belar +belay +belee +belga +bells +belon +belts +bemad +bemas +bemix +bemud +bends +bendy +benes +benet +benga +benis +benne +benni +benny +bento +bents +benty +bepat +beray +beres +bergs +berko +berks +berme +berms +berob +beryl +besat +besaw +besee +beses +besit +besom +besot +besti +bests +betas +beted +betes +beths +betid +beton +betta +betty +bever +bevor +bevue +bevvy +bewet +bewig +bezes +bezil +bezzy +bhais +bhaji +bhang +bhats +bhels +bhoot +bhuna +bhuts +biach +biali +bialy +bibbs +bibes +biccy +bices +bided +bider +bides +bidet +bidis +bidon +bield +biers +biffo +biffs +biffy +bifid +bigae +biggs +biggy +bigha +bight +bigly +bigos +bijou +biked +biker +bikes +bikie +bilbo +bilby +biled +biles +bilgy +bilks +bills +bimah +bimas +bimbo +binal +bindi +binds +biner +bines +bings +bingy +binit +binks +bints +biogs +biont +biota +biped +bipod +birds +birks +birle +birls +biros +birrs +birse +birsy +bises +bisks +bisom +bitch +biter +bites +bitos +bitou +bitsy +bitte +bitts +bivia +bivvy +bizes +bizzo +bizzy +blabs +blads +blady +blaer +blaes +blaff +blags +blahs +blain +blams +blart +blase +blash +blate +blats +blatt +blaud +blawn +blaws +blays +blear +blebs +blech +blees +blent +blert +blest +blets +bleys +blimy +bling +blini +blins +bliny +blips +blist +blite +blits +blive +blobs +blocs +blogs +blook +bloop +blore +blots +blows +blowy +blubs +blude +bluds +bludy +blued +blues +bluet +bluey +bluid +blume +blunk +blurs +blype +boabs +boaks +boars +boart +boats +bobac +bobak +bobas +bobol +bobos +bocca +bocce +bocci +boche +bocks +boded +bodes +bodge +bodhi +bodle +boeps +boets +boeuf +boffo +boffs +bogan +bogey +boggy +bogie +bogle +bogue +bogus +bohea +bohos +boils +boing +boink +boite +boked +bokeh +bokes +bokos +bolar +bolas +bolds +boles +bolix +bolls +bolos +bolts +bolus +bomas +bombe +bombo +bombs +bonce +bonds +boned +boner +bones +bongs +bonie +bonks +bonne +bonny +bonza +bonze +booai +booay +boobs +boody +booed +boofy +boogy +boohs +books +booky +bools +booms +boomy +boong +boons +boord +boors +boose +boots +boppy +borak +boral +boras +borde +bords +bored +boree +borel +borer +bores +borgo +boric +borks +borms +borna +boron +borts +borty +bortz +bosie +bosks +bosky +boson +bosun +botas +botel +botes +bothy +botte +botts +botty +bouge +bouks +boult +bouns +bourd +bourg +bourn +bouse +bousy +bouts +bovid +bowat +bowed +bower +bowes +bowet +bowie +bowls +bowne +bowrs +bowse +boxed +boxen +boxes +boxla +boxty +boyar +boyau +boyed +boyfs +boygs +boyla +boyos +boysy +bozos +braai +brach +brack +bract +brads +braes +brags +brail +braks +braky +brame +brane +brank +brans +brant +brast +brats +brava +bravi +braws +braxy +brays +braza +braze +bream +brede +breds +breem +breer +brees +breid +breis +breme +brens +brent +brere +brers +breve +brews +breys +brier +bries +brigs +briki +briks +brill +brims +brins +brios +brise +briss +brith +brits +britt +brize +broch +brock +brods +brogh +brogs +brome +bromo +bronc +brond +brool +broos +brose +brosy +brows +brugh +bruin +bruit +brule +brume +brung +brusk +brust +bruts +buats +buaze +bubal +bubas +bubba +bubbe +bubby +bubus +buchu +bucko +bucks +bucku +budas +budis +budos +buffa +buffe +buffi +buffo +buffs +buffy +bufos +bufty +buhls +buhrs +buiks +buist +bukes +bulbs +bulgy +bulks +bulla +bulls +bulse +bumbo +bumfs +bumph +bumps +bumpy +bunas +bunce +bunco +bunde +bundh +bunds +bundt +bundu +bundy +bungs +bungy +bunia +bunje +bunjy +bunko +bunks +bunns +bunts +bunty +bunya +buoys +buppy +buran +buras +burbs +burds +buret +burfi +burgh +burgs +burin +burka +burke +burks +burls +burns +buroo +burps +burqa +burro +burrs +burry +bursa +burse +busby +buses +busks +busky +bussu +busti +busts +busty +buteo +butes +butle +butoh +butts +butty +butut +butyl +buzzy +bwana +bwazi +byded +bydes +byked +bykes +byres +byrls +byssi +bytes +byway +caaed +cabas +caber +cabob +caboc +cabre +cacas +cacks +cacky +cadee +cades +cadge +cadgy +cadie +cadis +cadre +caeca +caese +cafes +caffs +caged +cager +cages +cagot +cahow +caids +cains +caird +cajon +cajun +caked +cakes +cakey +calfs +calid +calif +calix +calks +calla +calls +calms +calmy +calos +calpa +calps +calve +calyx +caman +camas +cames +camis +camos +campi +campo +camps +campy +camus +caned +caneh +caner +canes +cangs +canid +canna +canns +canso +canst +canto +cants +canty +capas +caped +capes +capex +caphs +capiz +caple +capon +capos +capot +capri +capul +carap +carbo +carbs +carby +cardi +cards +cardy +cared +carer +cares +caret +carex +carks +carle +carls +carns +carny +carob +carom +caron +carpi +carps +carrs +carse +carta +carte +carts +carvy +casas +casco +cased +cases +casks +casky +casts +casus +cates +cauda +cauks +cauld +cauls +caums +caups +cauri +causa +cavas +caved +cavel +caver +caves +cavie +cawed +cawks +caxon +ceaze +cebid +cecal +cecum +ceded +ceder +cedes +cedis +ceiba +ceili +ceils +celeb +cella +celli +cells +celom +celts +cense +cento +cents +centu +ceorl +cepes +cerci +cered +ceres +cerge +ceria +ceric +cerne +ceroc +ceros +certs +certy +cesse +cesta +cesti +cetes +cetyl +cezve +chace +chack +chaco +chado +chads +chaft +chais +chals +chams +chana +chang +chank +chape +chaps +chapt +chara +chare +chark +charr +chars +chary +chats +chave +chavs +chawk +chaws +chaya +chays +cheep +chefs +cheka +chela +chelp +chemo +chems +chere +chert +cheth +chevy +chews +chewy +chiao +chias +chibs +chica +chich +chico +chics +chiel +chiks +chile +chimb +chimo +chimp +chine +ching +chink +chino +chins +chips +chirk +chirl +chirm +chiro +chirr +chirt +chiru +chits +chive +chivs +chivy +chizz +choco +chocs +chode +chogs +choil +choko +choky +chola +choli +cholo +chomp +chons +choof +chook +choom +choon +chops +chota +chott +chout +choux +chowk +chows +chubs +chufa +chuff +chugs +chums +churl +churr +chuse +chuts +chyle +chyme +chynd +cibol +cided +cides +ciels +ciggy +cilia +cills +cimar +cimex +cinct +cines +cinqs +cions +cippi +circs +cires +cirls +cirri +cisco +cissy +cists +cital +cited +citer +cites +cives +civet +civie +civvy +clach +clade +clads +claes +clags +clame +clams +clans +claps +clapt +claro +clart +clary +clast +clats +claut +clave +clavi +claws +clays +cleck +cleek +cleep +clefs +clegs +cleik +clems +clepe +clept +cleve +clews +clied +clies +clift +clime +cline +clint +clipe +clips +clipt +clits +cloam +clods +cloff +clogs +cloke +clomb +clomp +clonk +clons +cloop +cloot +clops +clote +clots +clour +clous +clows +cloye +cloys +cloze +clubs +clues +cluey +clunk +clype +cnida +coact +coady +coala +coals +coaly +coapt +coarb +coate +coati +coats +cobbs +cobby +cobia +coble +cobza +cocas +cocci +cocco +cocks +cocky +cocos +codas +codec +coded +coden +coder +codes +codex +codon +coeds +coffs +cogie +cogon +cogue +cohab +cohen +cohoe +cohog +cohos +coifs +coign +coils +coins +coirs +coits +coked +cokes +colas +colby +colds +coled +coles +coley +colic +colin +colls +colly +colog +colts +colza +comae +comal +comas +combe +combi +combo +combs +comby +comer +comes +comix +commo +comms +commy +compo +comps +compt +comte +comus +coned +cones +coney +confs +conga +conge +congo +conia +conin +conks +conky +conne +conns +conte +conto +conus +convo +cooch +cooed +cooee +cooer +cooey +coofs +cooks +cooky +cools +cooly +coomb +cooms +coomy +coons +coops +coopt +coost +coots +cooze +copal +copay +coped +copen +coper +copes +coppy +copra +copsy +coqui +coram +corbe +corby +cords +cored +cores +corey +corgi +coria +corks +corky +corms +corni +corno +corns +cornu +corps +corse +corso +cosec +cosed +coses +coset +cosey +cosie +costa +coste +costs +cotan +coted +cotes +coths +cotta +cotts +coude +coups +courb +courd +coure +cours +couta +couth +coved +coves +covin +cowal +cowan +cowed +cowks +cowls +cowps +cowry +coxae +coxal +coxed +coxes +coxib +coyau +coyed +coyer +coypu +cozed +cozen +cozes +cozey +cozie +craal +crabs +crags +craic +craig +crake +crame +crams +crans +crape +craps +crapy +crare +craws +crays +creds +creel +crees +crems +crena +creps +crepy +crewe +crews +crias +cribs +cries +crims +crine +crios +cripe +crips +crise +crith +crits +croci +crocs +croft +crogs +cromb +crome +cronk +crons +crool +croon +crops +crore +crost +crout +crows +croze +cruck +crudo +cruds +crudy +crues +cruet +cruft +crunk +cruor +crura +cruse +crusy +cruve +crwth +cryer +ctene +cubby +cubeb +cubed +cuber +cubes +cubit +cuddy +cuffo +cuffs +cuifs +cuing +cuish +cuits +cukes +culch +culet +culex +culls +cully +culms +culpa +culti +cults +culty +cumec +cundy +cunei +cunit +cunts +cupel +cupid +cuppa +cuppy +curat +curbs +curch +curds +curdy +cured +curer +cures +curet +curfs +curia +curie +curli +curls +curns +curny +currs +cursi +curst +cusec +cushy +cusks +cusps +cuspy +cusso +cusum +cutch +cuter +cutes +cutey +cutin +cutis +cutto +cutty +cutup +cuvee +cuzes +cwtch +cyano +cyans +cycad +cycas +cyclo +cyder +cylix +cymae +cymar +cymas +cymes +cymol +cysts +cytes +cyton +czars +daals +dabba +daces +dacha +dacks +dadah +dadas +dados +daffs +daffy +dagga +daggy +dagos +dahls +daiko +daine +daint +daker +daled +dales +dalis +dalle +dalts +daman +damar +dames +damme +damns +damps +dampy +dancy +dangs +danio +danks +danny +dants +daraf +darbs +darcy +dared +darer +dares +darga +dargs +daric +daris +darks +darky +darns +darre +darts +darzi +dashi +dashy +datal +dated +dater +dates +datos +datto +daube +daubs +dauby +dauds +dault +daurs +dauts +daven +davit +dawah +dawds +dawed +dawen +dawks +dawns +dawts +dayan +daych +daynt +dazed +dazer +dazes +deads +deair +deals +deans +deare +dearn +dears +deary +deash +deave +deaws +deawy +debag +debby +debel +debes +debts +debud +debur +debus +debye +decad +decaf +decan +decko +decks +decos +dedal +deeds +deedy +deely +deems +deens +deeps +deere +deers +deets +deeve +deevs +defat +deffo +defis +defog +degas +degum +degus +deice +deids +deify +deils +deism +deist +deked +dekes +dekko +deled +deles +delfs +delft +delis +dells +delly +delos +delph +delts +deman +demes +demic +demit +demob +demoi +demos +dempt +denar +denay +dench +denes +denet +denis +dents +deoxy +derat +deray +dered +deres +derig +derma +derms +derns +derny +deros +derro +derry +derth +dervs +desex +deshi +desis +desks +desse +devas +devel +devis +devon +devos +devot +dewan +dewar +dewax +dewed +dexes +dexie +dhaba +dhaks +dhals +dhikr +dhobi +dhole +dholl +dhols +dhoti +dhows +dhuti +diact +dials +diane +diazo +dibbs +diced +dicer +dices +dicht +dicks +dicky +dicot +dicta +dicts +dicty +diddy +didie +didos +didst +diebs +diels +diene +diets +diffs +dight +dikas +diked +diker +dikes +dikey +dildo +dilli +dills +dimbo +dimer +dimes +dimps +dinar +dined +dines +dinge +dings +dinic +dinks +dinky +dinna +dinos +dints +diols +diota +dippy +dipso +diram +direr +dirke +dirks +dirls +dirts +disas +disci +discs +dishy +disks +disme +dital +ditas +dited +dites +ditsy +ditts +ditzy +divan +divas +dived +dives +divis +divna +divos +divot +divvy +diwan +dixie +dixit +diyas +dizen +djinn +djins +doabs +doats +dobby +dobes +dobie +dobla +dobra +dobro +docht +docks +docos +docus +doddy +dodos +doeks +doers +doest +doeth +doffs +dogan +doges +dogey +doggo +doggy +dogie +dohyo +doilt +doily +doits +dojos +dolce +dolci +doled +doles +dolia +dolls +dolma +dolor +dolos +dolts +domal +domed +domes +domic +donah +donas +donee +doner +donga +dongs +donko +donna +donne +donny +donsy +doobs +dooce +doody +dooks +doole +dools +dooly +dooms +doomy +doona +doorn +doors +doozy +dopas +doped +doper +dopes +dorad +dorba +dorbs +doree +dores +doric +doris +dorks +dorky +dorms +dormy +dorps +dorrs +dorsa +dorse +dorts +dorty +dosai +dosas +dosed +doseh +doser +doses +dosha +dotal +doted +doter +dotes +dotty +douar +douce +doucs +douks +doula +douma +doums +doups +doura +douse +douts +doved +doven +dover +doves +dovie +dowar +dowds +dowed +dower +dowie +dowle +dowls +dowly +downa +downs +dowps +dowse +dowts +doxed +doxes +doxie +doyen +doyly +dozed +dozer +dozes +drabs +drack +draco +draff +drags +drail +drams +drant +draps +drats +drave +draws +drays +drear +dreck +dreed +dreer +drees +dregs +dreks +drent +drere +drest +dreys +dribs +drice +dries +drily +drips +dript +droid +droil +droke +drole +drome +drony +droob +droog +drook +drops +dropt +drouk +drows +drubs +drugs +drums +drupe +druse +drusy +druxy +dryad +dryas +dsobo +dsomo +duads +duals +duans +duars +dubbo +ducal +ducat +duces +ducks +ducky +ducts +duddy +duded +dudes +duels +duets +duett +duffs +dufus +duing +duits +dukas +duked +dukes +dukka +dulce +dules +dulia +dulls +dulse +dumas +dumbo +dumbs +dumka +dumky +dumps +dunam +dunch +dunes +dungs +dungy +dunks +dunno +dunny +dunsh +dunts +duomi +duomo +duped +duper +dupes +duple +duply +duppy +dural +duras +dured +dures +durgy +durns +duroc +duros +duroy +durra +durrs +durry +durst +durum +durzi +dusks +dusts +duxes +dwaal +dwale +dwalm +dwams +dwang +dwaum +dweeb +dwile +dwine +dyads +dyers +dyked +dykes +dykey +dykon +dynel +dynes +dzhos +eagre +ealed +eales +eaned +eards +eared +earls +earns +earnt +earst +eased +easer +eases +easle +easts +eathe +eaved +eaves +ebbed +ebbet +ebons +ebook +ecads +eched +eches +echos +ecrus +edema +edged +edger +edges +edile +edits +educe +educt +eejit +eensy +eeven +eevns +effed +egads +egers +egest +eggar +egged +egger +egmas +ehing +eider +eidos +eigne +eiked +eikon +eilds +eisel +ejido +ekkas +elain +eland +elans +elchi +eldin +elemi +elfed +eliad +elint +elmen +eloge +elogy +eloin +elops +elpee +elsin +elute +elvan +elven +elver +elves +emacs +embar +embay +embog +embow +embox +embus +emeer +emend +emerg +emery +emeus +emics +emirs +emits +emmas +emmer +emmet +emmew +emmys +emoji +emong +emote +emove +empts +emule +emure +emyde +emyds +enarm +enate +ended +ender +endew +endue +enews +enfix +eniac +enlit +enmew +ennog +enoki +enols +enorm +enows +enrol +ensew +ensky +entia +enure +enurn +envoi +enzym +eorls +eosin +epact +epees +ephah +ephas +ephod +ephor +epics +epode +epopt +epris +eques +equid +erbia +erevs +ergon +ergos +ergot +erhus +erica +erick +erics +ering +erned +ernes +erose +erred +erses +eruct +erugo +eruvs +erven +ervil +escar +escot +esile +eskar +esker +esnes +esses +estoc +estop +estro +etage +etape +etats +etens +ethal +ethne +ethyl +etics +etnas +ettin +ettle +etuis +etwee +etyma +eughs +euked +eupad +euros +eusol +evens +evert +evets +evhoe +evils +evite +evohe +ewers +ewest +ewhow +ewked +exams +exeat +execs +exeem +exeme +exfil +exies +exine +exing +exits +exode +exome +exons +expat +expos +exude +exuls +exurb +eyass +eyers +eyots +eyras +eyres +eyrie +eyrir +ezine +fabby +faced +facer +faces +facia +facta +facts +faddy +faded +fader +fades +fadge +fados +faena +faery +faffs +faffy +faggy +fagin +fagot +faiks +fails +faine +fains +fairs +faked +faker +fakes +fakey +fakie +fakir +falaj +falls +famed +fames +fanal +fands +fanes +fanga +fango +fangs +fanks +fanon +fanos +fanum +faqir +farad +farci +farcy +fards +fared +farer +fares +farle +farls +farms +faros +farro +farse +farts +fasci +fasti +fasts +fated +fates +fatly +fatso +fatwa +faugh +fauld +fauns +faurd +fauts +fauve +favas +favel +faver +faves +favus +fawns +fawny +faxed +faxes +fayed +fayer +fayne +fayre +fazed +fazes +feals +feare +fears +feart +fease +feats +feaze +feces +fecht +fecit +fecks +fedex +feebs +feeds +feels +feens +feers +feese +feeze +fehme +feint +feist +felch +felid +fells +felly +felts +felty +femal +femes +femmy +fends +fendy +fenis +fenks +fenny +fents +feods +feoff +ferer +feres +feria +ferly +fermi +ferms +ferns +ferny +fesse +festa +fests +festy +fetas +feted +fetes +fetor +fetta +fetts +fetwa +feuar +feuds +feued +feyed +feyer +feyly +fezes +fezzy +fiars +fiats +fibro +fices +fiche +fichu +ficin +ficos +fides +fidge +fidos +fiefs +fient +fiere +fiers +fiest +fifed +fifer +fifes +fifis +figgy +figos +fiked +fikes +filar +filch +filed +files +filii +filks +fille +fillo +fills +filmi +films +filos +filum +finca +finds +fined +fines +finis +finks +finny +finos +fiord +fiqhs +fique +fired +firer +fires +firie +firks +firms +firns +firry +firth +fiscs +fisks +fists +fisty +fitch +fitly +fitna +fitte +fitts +fiver +fives +fixed +fixes +fixit +fjeld +flabs +flaff +flags +flaks +flamm +flams +flamy +flane +flans +flaps +flary +flats +flava +flawn +flaws +flawy +flaxy +flays +fleam +fleas +fleek +fleer +flees +flegs +fleme +fleur +flews +flexi +flexo +fleys +flics +flied +flies +flimp +flims +flips +flirs +flisk +flite +flits +flitt +flobs +flocs +floes +flogs +flong +flops +flors +flory +flosh +flota +flote +flows +flubs +flued +flues +fluey +fluky +flump +fluor +flurr +fluty +fluyt +flyby +flype +flyte +foals +foams +foehn +fogey +fogie +fogle +fogou +fohns +foids +foils +foins +folds +foley +folia +folic +folie +folks +folky +fomes +fonda +fonds +fondu +fones +fonly +fonts +foods +foody +fools +foots +footy +foram +forbs +forby +fordo +fords +forel +fores +forex +forks +forky +forme +forms +forts +forza +forze +fossa +fosse +fouat +fouds +fouer +fouet +foule +fouls +fount +fours +fouth +fovea +fowls +fowth +foxed +foxes +foxie +foyle +foyne +frabs +frack +fract +frags +fraim +franc +frape +fraps +frass +frate +frati +frats +fraus +frays +frees +freet +freit +fremd +frena +freon +frere +frets +fribs +frier +fries +frigs +frise +frist +frith +frits +fritt +frize +frizz +froes +frogs +frons +frore +frorn +frory +frosh +frows +frowy +frugs +frump +frush +frust +fryer +fubar +fubby +fubsy +fucks +fucus +fuddy +fudgy +fuels +fuero +fuffs +fuffy +fugal +fuggy +fugie +fugio +fugle +fugly +fugus +fujis +fulls +fumed +fumer +fumes +fumet +fundi +funds +fundy +fungo +fungs +funks +fural +furan +furca +furls +furol +furrs +furth +furze +furzy +fused +fusee +fusel +fuses +fusil +fusks +fusts +fusty +futon +fuzed +fuzee +fuzes +fuzil +fyces +fyked +fykes +fyles +fyrds +fytte +gabba +gabby +gable +gaddi +gades +gadge +gadid +gadis +gadje +gadjo +gadso +gaffs +gaged +gager +gages +gaids +gains +gairs +gaita +gaits +gaitt +gajos +galah +galas +galax +galea +galed +gales +galls +gally +galop +galut +galvo +gamas +gamay +gamba +gambe +gambo +gambs +gamed +games +gamey +gamic +gamin +gamme +gammy +gamps +ganch +gandy +ganef +ganev +gangs +ganja +ganof +gants +gaols +gaped +gaper +gapes +gapos +gappy +garbe +garbo +garbs +garda +gares +garis +garms +garni +garre +garth +garum +gases +gasps +gaspy +gasts +gatch +gated +gater +gates +gaths +gator +gauch +gaucy +gauds +gauje +gault +gaums +gaumy +gaups +gaurs +gauss +gauzy +gavot +gawcy +gawds +gawks +gawps +gawsy +gayal +gazal +gazar +gazed +gazes +gazon +gazoo +geals +geans +geare +gears +geats +gebur +gecks +geeks +geeps +geest +geist +geits +gelds +gelee +gelid +gelly +gelts +gemel +gemma +gemmy +gemot +genal +genas +genes +genet +genic +genii +genip +genny +genoa +genom +genro +gents +genty +genua +genus +geode +geoid +gerah +gerbe +geres +gerle +germs +germy +gerne +gesse +gesso +geste +gests +getas +getup +geums +geyan +geyer +ghast +ghats +ghaut +ghazi +ghees +ghest +ghyll +gibed +gibel +giber +gibes +gibli +gibus +gifts +gigas +gighe +gigot +gigue +gilas +gilds +gilet +gills +gilly +gilpy +gilts +gimel +gimme +gimps +gimpy +ginch +ginge +gings +ginks +ginny +ginzo +gipon +gippo +gippy +girds +girls +girns +giron +giros +girrs +girsh +girts +gismo +gisms +gists +gitch +gites +giust +gived +gives +gizmo +glace +glads +glady +glaik +glair +glams +glans +glary +glaum +glaur +glazy +gleba +glebe +gleby +glede +gleds +gleed +gleek +glees +gleet +gleis +glens +glent +gleys +glial +glias +glibs +gliff +glift +glike +glime +glims +glisk +glits +glitz +gloam +globi +globs +globy +glode +glogg +gloms +gloop +glops +glost +glout +glows +gloze +glued +gluer +glues +gluey +glugs +glume +glums +gluon +glute +gluts +gnarl +gnarr +gnars +gnats +gnawn +gnaws +gnows +goads +goafs +goals +goary +goats +goaty +goban +gobar +gobbi +gobbo +gobby +gobis +gobos +godet +godso +goels +goers +goest +goeth +goety +gofer +goffs +gogga +gogos +goier +gojis +golds +goldy +goles +golfs +golpe +golps +gombo +gomer +gompa +gonch +gonef +gongs +gonia +gonif +gonks +gonna +gonof +gonys +gonzo +gooby +goods +goofs +googs +gooks +gooky +goold +gools +gooly +goons +goony +goops +goopy +goors +goory +goosy +gopak +gopik +goral +goras +gored +gores +goris +gorms +gormy +gorps +gorse +gorsy +gosht +gosse +gotch +goths +gothy +gotta +gouch +gouks +goura +gouts +gouty +gowan +gowds +gowfs +gowks +gowls +gowns +goxes +goyim +goyle +graal +grabs +grads +graff +graip +grama +grame +gramp +grams +grana +grans +grapy +gravs +grays +grebe +grebo +grece +greek +grees +grege +grego +grein +grens +grese +greve +grews +greys +grice +gride +grids +griff +grift +grigs +grike +grins +griot +grips +gript +gripy +grise +grist +grisy +grith +grits +grize +groat +grody +grogs +groks +groma +grone +groof +grosz +grots +grouf +grovy +grows +grrls +grrrl +grubs +grued +grues +grufe +grume +grump +grund +gryce +gryde +gryke +grype +grypt +guaco +guana +guano +guans +guars +gucks +gucky +gudes +guffs +gugas +guids +guimp +guiro +gulag +gular +gulas +gules +gulet +gulfs +gulfy +gulls +gulph +gulps +gulpy +gumma +gummi +gumps +gundy +gunge +gungy +gunks +gunky +gunny +guqin +gurdy +gurge +gurls +gurly +gurns +gurry +gursh +gurus +gushy +gusla +gusle +gusli +gussy +gusts +gutsy +gutta +gutty +guyed +guyle +guyot +guyse +gwine +gyals +gyans +gybed +gybes +gyeld +gymps +gynae +gynie +gynny +gynos +gyoza +gypos +gyppo +gyppy +gyral +gyred +gyres +gyron +gyros +gyrus +gytes +gyved +gyves +haafs +haars +hable +habus +hacek +hacks +hadal +haded +hades +hadji +hadst +haems +haets +haffs +hafiz +hafts +haggs +hahas +haick +haika +haiks +haiku +hails +haily +hains +haint +hairs +haith +hajes +hajis +hajji +hakam +hakas +hakea +hakes +hakim +hakus +halal +haled +haler +hales +halfa +halfs +halid +hallo +halls +halma +halms +halon +halos +halse +halts +halva +halwa +hamal +hamba +hamed +hames +hammy +hamza +hanap +hance +hanch +hands +hangi +hangs +hanks +hanky +hansa +hanse +hants +haole +haoma +hapax +haply +happi +hapus +haram +hards +hared +hares +harim +harks +harls +harms +harns +haros +harps +harts +hashy +hasks +hasps +hasta +hated +hates +hatha +hauds +haufs +haugh +hauld +haulm +hauls +hault +hauns +hause +haver +haves +hawed +hawks +hawms +hawse +hayed +hayer +hayey +hayle +hazan +hazed +hazer +hazes +heads +heald +heals +heame +heaps +heapy +heare +hears +heast +heats +heben +hebes +hecht +hecks +heder +hedgy +heeds +heedy +heels +heeze +hefte +hefts +heids +heigh +heils +heirs +hejab +hejra +heled +heles +helio +hells +helms +helos +helot +helps +helve +hemal +hemes +hemic +hemin +hemps +hempy +hench +hends +henge +henna +henny +henry +hents +hepar +herbs +herby +herds +heres +herls +herma +herms +herns +heros +herry +herse +hertz +herye +hesps +hests +hetes +heths +heuch +heugh +hevea +hewed +hewer +hewgh +hexad +hexed +hexer +hexes +hexyl +heyed +hiant +hicks +hided +hider +hides +hiems +highs +hight +hijab +hijra +hiked +hiker +hikes +hikoi +hilar +hilch +hillo +hills +hilts +hilum +hilus +himbo +hinau +hinds +hings +hinky +hinny +hints +hiois +hiply +hired +hiree +hirer +hires +hissy +hists +hithe +hived +hiver +hives +hizen +hoaed +hoagy +hoars +hoary +hoast +hobos +hocks +hocus +hodad +hodja +hoers +hogan +hogen +hoggs +hoghs +hohed +hoick +hoied +hoiks +hoing +hoise +hokas +hoked +hokes +hokey +hokis +hokku +hokum +holds +holed +holes +holey +holks +holla +hollo +holme +holms +holon +holos +holts +homas +homed +homes +homey +homie +homme +homos +honan +honda +honds +honed +honer +hones +hongi +hongs +honks +honky +hooch +hoods +hoody +hooey +hoofs +hooka +hooks +hooky +hooly +hoons +hoops +hoord +hoors +hoosh +hoots +hooty +hoove +hopak +hoped +hoper +hopes +hoppy +horah +horal +horas +horis +horks +horme +horns +horst +horsy +hosed +hosel +hosen +hoser +hoses +hosey +hosta +hosts +hotch +hoten +hotty +houff +houfs +hough +houri +hours +houts +hovea +hoved +hoven +hoves +howbe +howes +howff +howfs +howks +howls +howre +howso +hoxed +hoxes +hoyas +hoyed +hoyle +hubby +hucks +hudna +hudud +huers +huffs +huffy +huger +huggy +huhus +huias +hulas +hules +hulks +hulky +hullo +hulls +hully +humas +humfs +humic +humps +humpy +hunks +hunts +hurds +hurls +hurly +hurra +hurst +hurts +hushy +husks +husos +hutia +huzza +huzzy +hwyls +hydra +hyens +hygge +hying +hykes +hylas +hyleg +hyles +hylic +hymns +hynde +hyoid +hyped +hypes +hypha +hyphy +hypos +hyrax +hyson +hythe +iambi +iambs +ibrik +icers +iched +iches +ichor +icier +icker +ickle +icons +ictal +ictic +ictus +idant +ideas +idees +ident +idled +idles +idola +idols +idyls +iftar +igapo +igged +iglus +ihram +ikans +ikats +ikons +ileac +ileal +ileum +ileus +iliad +ilial +ilium +iller +illth +imago +imams +imari +imaum +imbar +imbed +imide +imido +imids +imine +imino +immew +immit +immix +imped +impis +impot +impro +imshi +imshy +inapt +inarm +inbye +incel +incle +incog +incus +incut +indew +india +indie +indol +indow +indri +indue +inerm +infix +infos +infra +ingan +ingle +inion +inked +inker +inkle +inned +innit +inorb +inrun +inset +inspo +intel +intil +intis +intra +inula +inure +inurn +inust +invar +inwit +iodic +iodid +iodin +iotas +ippon +irade +irids +iring +irked +iroko +irone +irons +isbas +ishes +isled +isles +isnae +issei +istle +items +ither +ivied +ivies +ixias +ixnay +ixora +ixtle +izard +izars +izzat +jaaps +jabot +jacal +jacks +jacky +jaded +jades +jafas +jaffa +jagas +jager +jaggs +jaggy +jagir +jagra +jails +jaker +jakes +jakey +jalap +jalop +jambe +jambo +jambs +jambu +james +jammy +jamon +janes +janns +janny +janty +japan +japed +japer +japes +jarks +jarls +jarps +jarta +jarul +jasey +jaspe +jasps +jatos +jauks +jaups +javas +javel +jawan +jawed +jaxie +jeans +jeats +jebel +jedis +jeels +jeely +jeeps +jeers +jeeze +jefes +jeffs +jehad +jehus +jelab +jello +jells +jembe +jemmy +jenny +jeons +jerid +jerks +jerry +jesse +jests +jesus +jetes +jeton +jeune +jewed +jewie +jhala +jiaos +jibba +jibbs +jibed +jiber +jibes +jiffs +jiggy +jigot +jihad +jills +jilts +jimmy +jimpy +jingo +jinks +jinne +jinni +jinns +jirds +jirga +jirre +jisms +jived +jiver +jives +jivey +jnana +jobed +jobes +jocko +jocks +jocky +jocos +jodel +joeys +johns +joins +joked +jokes +jokey +jokol +joled +joles +jolls +jolts +jolty +jomon +jomos +jones +jongs +jonty +jooks +joram +jorum +jotas +jotty +jotun +joual +jougs +jouks +joule +jours +jowar +jowed +jowls +jowly +joyed +jubas +jubes +jucos +judas +judgy +judos +jugal +jugum +jujus +juked +jukes +jukus +julep +jumar +jumby +jumps +junco +junks +junky +jupes +jupon +jural +jurat +jurel +jures +justs +jutes +jutty +juves +juvie +kaama +kabab +kabar +kabob +kacha +kacks +kadai +kades +kadis +kafir +kagos +kagus +kahal +kaiak +kaids +kaies +kaifs +kaika +kaiks +kails +kaims +kaing +kains +kakas +kakis +kalam +kales +kalif +kalis +kalpa +kamas +kames +kamik +kamis +kamme +kanae +kanas +kandy +kaneh +kanes +kanga +kangs +kanji +kants +kanzu +kaons +kapas +kaphs +kapok +kapow +kapus +kaput +karas +karat +karks +karns +karoo +karos +karri +karst +karsy +karts +karzy +kasha +kasme +katal +katas +katis +katti +kaugh +kauri +kauru +kaury +kaval +kavas +kawas +kawau +kawed +kayle +kayos +kazis +kazoo +kbars +kebar +kebob +kecks +kedge +kedgy +keech +keefs +keeks +keels +keema +keeno +keens +keeps +keets +keeve +kefir +kehua +keirs +kelep +kelim +kells +kelly +kelps +kelpy +kelts +kelty +kembo +kembs +kemps +kempt +kempy +kenaf +kench +kendo +kenos +kente +kents +kepis +kerbs +kerel +kerfs +kerky +kerma +kerne +kerns +keros +kerry +kerve +kesar +kests +ketas +ketch +ketes +ketol +kevel +kevil +kexes +keyed +keyer +khadi +khafs +khans +khaph +khats +khaya +khazi +kheda +kheth +khets +khoja +khors +khoum +khuds +kiaat +kiack +kiang +kibbe +kibbi +kibei +kibes +kibla +kicks +kicky +kiddo +kiddy +kidel +kidge +kiefs +kiers +kieve +kievs +kight +kikes +kikoi +kiley +kilim +kills +kilns +kilos +kilps +kilts +kilty +kimbo +kinas +kinda +kinds +kindy +kines +kings +kinin +kinks +kinos +kiore +kipes +kippa +kipps +kirby +kirks +kirns +kirri +kisan +kissy +kists +kited +kiter +kites +kithe +kiths +kitul +kivas +kiwis +klang +klaps +klett +klick +klieg +kliks +klong +kloof +kluge +klutz +knags +knaps +knarl +knars +knaur +knawe +knees +knell +knish +knits +knive +knobs +knops +knosp +knots +knout +knowe +knows +knubs +knurl +knurr +knurs +knuts +koans +koaps +koban +kobos +koels +koffs +kofta +kogal +kohas +kohen +kohls +koine +kojis +kokam +kokas +koker +kokra +kokum +kolas +kolos +kombu +konbu +kondo +konks +kooks +kooky +koori +kopek +kophs +kopje +koppa +korai +koras +korat +kores +korma +koros +korun +korus +koses +kotch +kotos +kotow +koura +kraal +krabs +kraft +krais +krait +krang +krans +kranz +kraut +krays +kreep +kreng +krewe +krona +krone +kroon +krubi +krunk +ksars +kubie +kudos +kudus +kudzu +kufis +kugel +kuias +kukri +kukus +kulak +kulan +kulas +kulfi +kumis +kumys +kuris +kurre +kurta +kurus +kusso +kutas +kutch +kutis +kutus +kuzus +kvass +kvell +kwela +kyack +kyaks +kyang +kyars +kyats +kybos +kydst +kyles +kylie +kylin +kylix +kyloe +kynde +kynds +kypes +kyrie +kytes +kythe +laari +labda +labia +labis +labra +laced +lacer +laces +lacet +lacey +lacks +laddy +laded +lader +lades +laers +laevo +lagan +lahal +lahar +laich +laics +laids +laigh +laika +laiks +laird +lairs +lairy +laith +laity +laked +laker +lakes +lakhs +lakin +laksa +laldy +lalls +lamas +lambs +lamby +lamed +lamer +lames +lamia +lammy +lamps +lanai +lanas +lanch +lande +lands +lanes +lanks +lants +lapin +lapis +lapje +larch +lards +lardy +laree +lares +largo +laris +larks +larky +larns +larnt +larum +lased +laser +lases +lassi +lassu +lassy +lasts +latah +lated +laten +latex +lathi +laths +lathy +latke +latus +lauan +lauch +lauds +laufs +laund +laura +laval +lavas +laved +laver +laves +lavra +lavvy +lawed +lawer +lawin +lawks +lawns +lawny +laxed +laxer +laxes +laxly +layed +layin +layup +lazar +lazed +lazes +lazos +lazzi +lazzo +leads +leady +leafs +leaks +leams +leans +leany +leaps +leare +lears +leary +leats +leavy +leaze +leben +leccy +ledes +ledgy +ledum +leear +leeks +leeps +leers +leese +leets +leeze +lefte +lefts +leger +leges +legge +leggo +legit +lehrs +lehua +leirs +leish +leman +lemed +lemel +lemes +lemma +lemme +lends +lenes +lengs +lenis +lenos +lense +lenti +lento +leone +lepid +lepra +lepta +lered +leres +lerps +lesbo +leses +lests +letch +lethe +letup +leuch +leuco +leuds +leugh +levas +levee +leves +levin +levis +lewis +lexes +lexis +lezes +lezza +lezzy +liana +liane +liang +liard +liars +liart +liber +libra +libri +lichi +licht +licit +licks +lidar +lidos +liefs +liens +liers +lieus +lieve +lifer +lifes +lifts +ligan +liger +ligge +ligne +liked +liker +likes +likin +lills +lilos +lilts +liman +limas +limax +limba +limbi +limbs +limby +limed +limen +limes +limey +limma +limns +limos +limpa +limps +linac +linch +linds +lindy +lined +lines +liney +linga +lings +lingy +linin +links +linky +linns +linny +linos +lints +linty +linum +linux +lions +lipas +lipes +lipin +lipos +lippy +liras +lirks +lirot +lisks +lisle +lisps +lists +litai +litas +lited +liter +lites +litho +liths +litre +lived +liven +lives +livor +livre +llano +loach +loads +loafs +loams +loans +loast +loave +lobar +lobed +lobes +lobos +lobus +loche +lochs +locie +locis +locks +locos +locum +loden +lodes +loess +lofts +logan +loges +loggy +logia +logie +logoi +logon +logos +lohan +loids +loins +loipe +loirs +lokes +lolls +lolly +lolog +lomas +lomed +lomes +loner +longa +longe +longs +looby +looed +looey +loofa +loofs +looie +looks +looky +looms +loons +loony +loops +loord +loots +loped +loper +lopes +loppy +loral +loran +lords +lordy +lorel +lores +loric +loris +losed +losel +losen +loses +lossy +lotah +lotas +lotes +lotic +lotos +lotsa +lotta +lotte +lotto +lotus +loued +lough +louie +louis +louma +lound +louns +loupe +loups +loure +lours +loury +louts +lovat +loved +loves +lovey +lovie +lowan +lowed +lowes +lownd +lowne +lowns +lowps +lowry +lowse +lowts +loxed +loxes +lozen +luach +luaus +lubed +lubes +lubra +luces +lucks +lucre +ludes +ludic +ludos +luffa +luffs +luged +luger +luges +lulls +lulus +lumas +lumbi +lumme +lummy +lumps +lunas +lunes +lunet +lungi +lungs +lunks +lunts +lupin +lured +lurer +lures +lurex +lurgi +lurgy +lurks +lurry +lurve +luser +lushy +lusks +lusts +lusus +lutea +luted +luter +lutes +luvvy +luxed +luxer +luxes +lweis +lyams +lyard +lyart +lyase +lycea +lycee +lycra +lymes +lynes +lyres +lysed +lyses +lysin +lysis +lysol +lyssa +lyted +lytes +lythe +lytic +lytta +maaed +maare +maars +mabes +macas +maced +macer +maces +mache +machi +machs +macks +macle +macon +madge +madid +madre +maerl +mafic +mages +maggs +magot +magus +mahoe +mahua +mahwa +maids +maiko +maiks +maile +maill +mails +maims +mains +maire +mairs +maise +maist +makar +makes +makis +makos +malam +malar +malas +malax +males +malic +malik +malis +malls +malms +malmy +malts +malty +malus +malva +malwa +mamas +mamba +mamee +mamey +mamie +manas +manat +mandi +maneb +maned +maneh +manes +manet +mangs +manis +manky +manna +manos +manse +manta +manto +manty +manul +manus +mapau +maqui +marae +marah +maras +marcs +mardy +mares +marge +margs +maria +marid +marka +marks +marle +marls +marly +marms +maron +maror +marra +marri +marse +marts +marvy +masas +mased +maser +mases +mashy +masks +massa +massy +masts +masty +masus +matai +mated +mater +mates +maths +matin +matlo +matte +matts +matza +matzo +mauby +mauds +mauls +maund +mauri +mausy +mauts +mauzy +maven +mavie +mavin +mavis +mawed +mawks +mawky +mawns +mawrs +maxed +maxes +maxis +mayan +mayas +mayed +mayos +mayst +mazed +mazer +mazes +mazey +mazut +mbira +meads +meals +meane +means +meany +meare +mease +meath +meats +mebos +mechs +mecks +medii +medle +meeds +meers +meets +meffs +meins +meint +meiny +meith +mekka +melas +melba +melds +melic +melik +mells +melts +melty +memes +memos +menad +mends +mened +menes +menge +mengs +mensa +mense +mensh +menta +mento +menus +meous +meows +merch +mercs +merde +mered +merel +merer +meres +meril +meris +merks +merle +merls +merse +mesal +mesas +mesel +meses +meshy +mesic +mesne +meson +messy +mesto +meted +metes +metho +meths +metic +metif +metis +metol +metre +meuse +meved +meves +mewed +mewls +meynt +mezes +mezze +mezzo +mhorr +miaou +miaow +miasm +miaul +micas +miche +micht +micks +micky +micos +micra +middy +midgy +midis +miens +mieve +miffs +miffy +mifty +miggs +mihas +mihis +miked +mikes +mikra +mikva +milch +milds +miler +miles +milfs +milia +milko +milks +mille +mills +milor +milos +milpa +milts +milty +miltz +mimed +mimeo +mimer +mimes +mimsy +minae +minar +minas +mincy +minds +mined +mines +minge +mings +mingy +minis +minke +minks +minny +minos +mints +mired +mires +mirex +mirid +mirin +mirks +mirky +mirly +miros +mirvs +mirza +misch +misdo +mises +misgo +misos +missa +mists +misty +mitch +miter +mites +mitis +mitre +mitts +mixed +mixen +mixer +mixes +mixte +mixup +mizen +mizzy +mneme +moans +moats +mobby +mobes +mobey +mobie +moble +mochi +mochs +mochy +mocks +moder +modes +modge +modii +modus +moers +mofos +moggy +mohel +mohos +mohrs +mohua +mohur +moile +moils +moira +moire +moits +mojos +mokes +mokis +mokos +molal +molas +molds +moled +moles +molla +molls +molly +molto +molts +molys +momes +momma +mommy +momus +monad +monal +monas +monde +mondo +moner +mongo +mongs +monic +monie +monks +monos +monte +monty +moobs +mooch +moods +mooed +mooks +moola +mooli +mools +mooly +moong +moons +moony +moops +moors +moory +moots +moove +moped +moper +mopes +mopey +moppy +mopsy +mopus +morae +moras +morat +moray +morel +mores +moria +morne +morns +morra +morro +morse +morts +mosed +moses +mosey +mosks +mosso +moste +mosts +moted +moten +motes +motet +motey +moths +mothy +motis +motte +motts +motty +motus +motza +mouch +moues +mould +mouls +moups +moust +mousy +moved +moves +mowas +mowed +mowra +moxas +moxie +moyas +moyle +moyls +mozed +mozes +mozos +mpret +mucho +mucic +mucid +mucin +mucks +mucor +mucro +mudge +mudir +mudra +muffs +mufti +mugga +muggs +muggy +muhly +muids +muils +muirs +muist +mujik +mulct +muled +mules +muley +mulga +mulie +mulla +mulls +mulse +mulsh +mumms +mumps +mumsy +mumus +munga +munge +mungo +mungs +munis +munts +muntu +muons +muras +mured +mures +murex +murid +murks +murls +murly +murra +murre +murri +murrs +murry +murti +murva +musar +musca +mused +muser +muses +muset +musha +musit +musks +musos +musse +mussy +musth +musts +mutch +muted +muter +mutes +mutha +mutis +muton +mutts +muxed +muxes +muzak +muzzy +mvule +myall +mylar +mynah +mynas +myoid +myoma +myope +myops +myopy +mysid +mythi +myths +mythy +myxos +mzees +naams +naans +nabes +nabis +nabks +nabla +nabob +nache +nacho +nacre +nadas +naeve +naevi +naffs +nagas +naggy +nagor +nahal +naiad +naifs +naiks +nails +naira +nairu +naked +naker +nakfa +nalas +naled +nalla +named +namer +names +namma +namus +nanas +nance +nancy +nandu +nanna +nanos +nanua +napas +naped +napes +napoo +nappa +nappe +nappy +naras +narco +narcs +nards +nares +naric +naris +narks +narky +narre +nashi +natch +nates +natis +natty +nauch +naunt +navar +naves +navew +navvy +nawab +nazes +nazir +nazis +nduja +neafe +neals +neaps +nears +neath +neats +nebek +nebel +necks +neddy +needs +neeld +neele +neemb +neems +neeps +neese +neeze +negro +negus +neifs +neist +neive +nelis +nelly +nemas +nemns +nempt +nenes +neons +neper +nepit +neral +nerds +nerka +nerks +nerol +nerts +nertz +nervy +nests +netes +netop +netts +netty +neuks +neume +neums +nevel +neves +nevus +newbs +newed +newel +newie +newsy +newts +nexts +nexus +ngaio +ngana +ngati +ngoma +ngwee +nicad +nicht +nicks +nicol +nidal +nided +nides +nidor +nidus +niefs +nieve +nifes +niffs +niffy +nifty +niger +nighs +nihil +nikab +nikah +nikau +nills +nimbi +nimbs +nimps +niner +nines +ninon +nipas +nippy +niqab +nirls +nirly +nisei +nisse +nisus +niter +nites +nitid +niton +nitre +nitro +nitry +nitty +nival +nixed +nixer +nixes +nixie +nizam +nkosi +noahs +nobby +nocks +nodal +noddy +nodes +nodus +noels +noggs +nohow +noils +noily +noint +noirs +noles +nolls +nolos +nomas +nomen +nomes +nomic +nomoi +nomos +nonas +nonce +nones +nonet +nongs +nonis +nonny +nonyl +noobs +nooit +nooks +nooky +noons +noops +nopal +noria +noris +norks +norma +norms +nosed +noser +noses +notal +noted +noter +notes +notum +nould +noule +nouls +nouns +nouny +noups +novae +novas +novum +noway +nowed +nowls +nowts +nowty +noxal +noxes +noyau +noyed +noyes +nubby +nubia +nucha +nuddy +nuder +nudes +nudie +nudzh +nuffs +nugae +nuked +nukes +nulla +nulls +numbs +numen +nummy +nunny +nurds +nurdy +nurls +nurrs +nutso +nutsy +nyaff +nyala +nying +nyssa +oaked +oaker +oakum +oared +oases +oasis +oasts +oaten +oater +oaths +oaves +obang +obeah +obeli +obeys +obias +obied +obiit +obits +objet +oboes +obole +oboli +obols +occam +ocher +oches +ochre +ochry +ocker +ocrea +octad +octan +octas +octyl +oculi +odahs +odals +odeon +odeum +odism +odist +odium +odors +odour +odyle +odyls +ofays +offed +offie +oflag +ofter +ogams +ogeed +ogees +oggin +ogham +ogive +ogled +ogler +ogles +ogmic +ogres +ohias +ohing +ohmic +ohone +oidia +oiled +oiler +oinks +oints +ojime +okapi +okays +okehs +okras +oktas +oldie +oleic +olein +olent +oleos +oleum +olios +ollas +ollav +oller +ollie +ology +olpae +olpes +omasa +omber +ombus +omens +omers +omits +omlah +omovs +omrah +oncer +onces +oncet +oncus +onely +oners +onery +onium +onkus +onlay +onned +ontic +oobit +oohed +oomph +oonts +ooped +oorie +ooses +ootid +oozed +oozes +opahs +opals +opens +opepe +oping +oppos +opsin +opted +opter +orach +oracy +orals +orang +orant +orate +orbed +orcas +orcin +ordos +oread +orfes +orgia +orgic +orgue +oribi +oriel +orixa +orles +orlon +orlop +ormer +ornis +orpin +orris +ortho +orval +orzos +oscar +oshac +osier +osmic +osmol +ossia +ostia +otaku +otary +ottar +ottos +oubit +oucht +ouens +ouija +oulks +oumas +oundy +oupas +ouped +ouphe +ouphs +ourie +ousel +ousts +outby +outed +outre +outro +outta +ouzel +ouzos +ovals +ovels +ovens +overs +ovist +ovoli +ovolo +ovule +owche +owies +owled +owler +owlet +owned +owres +owrie +owsen +oxbow +oxers +oxeye +oxids +oxies +oxime +oxims +oxlip +oxter +oyers +ozeki +ozzie +paals +paans +pacas +paced +pacer +paces +pacey +pacha +packs +pacos +pacta +pacts +padis +padle +padma +padre +padri +paean +paedo +paeon +paged +pager +pages +pagle +pagod +pagri +paiks +pails +pains +paire +pairs +paisa +paise +pakka +palas +palay +palea +paled +pales +palet +palis +palki +palla +palls +pally +palms +palmy +palpi +palps +palsa +pampa +panax +pance +panda +pands +pandy +paned +panes +panga +pangs +panim +panko +panne +panni +panto +pants +panty +paoli +paolo +papas +papaw +papes +pappi +pappy +parae +paras +parch +pardi +pards +pardy +pared +paren +pareo +pares +pareu +parev +parge +pargo +paris +parki +parks +parky +parle +parly +parma +parol +parps +parra +parrs +parti +parts +parve +parvo +paseo +pases +pasha +pashm +paska +paspy +passe +pasts +pated +paten +pater +pates +paths +patin +patka +patly +patte +patus +pauas +pauls +pavan +paved +paven +paver +paves +pavid +pavin +pavis +pawas +pawaw +pawed +pawer +pawks +pawky +pawls +pawns +paxes +payed +payor +paysd +peage +peags +peaks +peaky +peals +peans +peare +pears +peart +pease +peats +peaty +peavy +peaze +pebas +pechs +pecke +pecks +pecky +pedes +pedis +pedro +peece +peeks +peels +peens +peeoy +peepe +peeps +peers +peery +peeve +peggy +peghs +peins +peise +peize +pekan +pekes +pekin +pekoe +pelas +pelau +peles +pelfs +pells +pelma +pelon +pelta +pelts +pends +pendu +pened +penes +pengo +penie +penis +penks +penna +penni +pents +peons +peony +pepla +pepos +peppy +pepsi +perai +perce +percs +perdu +perdy +perea +peres +peris +perks +perms +perns +perog +perps +perry +perse +perst +perts +perve +pervo +pervs +pervy +pesos +pests +pesty +petar +peter +petit +petre +petri +petti +petto +pewee +pewit +peyse +phage +phang +phare +pharm +pheer +phene +pheon +phese +phial +phish +phizz +phlox +phoca +phono +phons +phots +phpht +phuts +phyla +phyle +piani +pians +pibal +pical +picas +piccy +picks +picot +picra +picul +piend +piers +piert +pieta +piets +piezo +pight +pigmy +piing +pikas +pikau +piked +piker +pikes +pikey +pikis +pikul +pilae +pilaf +pilao +pilar +pilau +pilaw +pilch +pilea +piled +pilei +piler +piles +pilis +pills +pilow +pilum +pilus +pimas +pimps +pinas +pined +pines +pingo +pings +pinko +pinks +pinna +pinny +pinon +pinot +pinta +pints +pinup +pions +piony +pious +pioye +pioys +pipal +pipas +piped +pipes +pipet +pipis +pipit +pippy +pipul +pirai +pirls +pirns +pirog +pisco +pises +pisky +pisos +pissy +piste +pitas +piths +piton +pitot +pitta +piums +pixes +pized +pizes +plaas +plack +plage +plans +plaps +plash +plasm +plast +plats +platt +platy +playa +plays +pleas +plebe +plebs +plena +pleon +plesh +plews +plica +plies +plims +pling +plink +ploat +plods +plong +plonk +plook +plops +plots +plotz +plouk +plows +ploye +ploys +plues +pluff +plugs +plums +plumy +pluot +pluto +plyer +poach +poaka +poake +poboy +pocks +pocky +podal +poddy +podex +podge +podgy +podia +poems +poeps +poets +pogey +pogge +pogos +pohed +poilu +poind +pokal +poked +pokes +pokey +pokie +poled +poler +poles +poley +polio +polis +polje +polks +polls +polly +polos +polts +polys +pombe +pomes +pommy +pomos +pomps +ponce +poncy +ponds +pones +poney +ponga +pongo +pongs +pongy +ponks +ponts +ponty +ponzu +poods +pooed +poofs +poofy +poohs +pooja +pooka +pooks +pools +poons +poops +poopy +poori +poort +poots +poove +poovy +popes +poppa +popsy +porae +poral +pored +porer +pores +porge +porgy +porin +porks +porky +porno +porns +porny +porta +ports +porty +posed +poses +posey +posho +posts +potae +potch +poted +potes +potin +potoo +potsy +potto +potts +potty +pouff +poufs +pouke +pouks +poule +poulp +poult +poupe +poupt +pours +pouts +powan +powin +pownd +powns +powny +powre +poxed +poxes +poynt +poyou +poyse +pozzy +praam +prads +prahu +prams +prana +prang +praos +prase +prate +prats +pratt +praty +praus +prays +predy +preed +prees +preif +prems +premy +prent +preon +preop +preps +presa +prese +prest +preve +prexy +preys +prial +pricy +prief +prier +pries +prigs +prill +prima +primi +primp +prims +primy +prink +prion +prise +priss +proas +probs +prods +proem +profs +progs +proin +proke +prole +proll +promo +proms +pronk +props +prore +proso +pross +prost +prosy +proto +proul +prows +proyn +prunt +pruta +pryer +pryse +pseud +pshaw +psion +psoae +psoai +psoas +psora +psych +psyop +pubco +pubes +pubis +pucan +pucer +puces +pucka +pucks +puddy +pudge +pudic +pudor +pudsy +pudus +puers +puffa +puffs +puggy +pugil +puhas +pujah +pujas +pukas +puked +puker +pukes +pukey +pukka +pukus +pulao +pulas +puled +puler +pules +pulik +pulis +pulka +pulks +pulli +pulls +pully +pulmo +pulps +pulus +pumas +pumie +pumps +punas +punce +punga +pungs +punji +punka +punks +punky +punny +punto +punts +punty +pupae +pupas +pupus +purda +pured +pures +purin +puris +purls +purpy +purrs +pursy +purty +puses +pusle +pussy +putid +puton +putti +putto +putts +puzel +pwned +pyats +pyets +pygal +pyins +pylon +pyned +pynes +pyoid +pyots +pyral +pyran +pyres +pyrex +pyric +pyros +pyxed +pyxes +pyxie +pyxis +pzazz +qadis +qaids +qajaq +qanat +qapik +qibla +qophs +qorma +quads +quaff +quags +quair +quais +quaky +quale +quant +quare +quass +quate +quats +quayd +quays +qubit +quean +queme +quena +quern +queyn +queys +quich +quids +quiff +quims +quina +quine +quino +quins +quint +quipo +quips +quipu +quire +quirt +quist +quits +quoad +quods +quoif +quoin +quoit +quoll +quonk +quops +qursh +quyte +rabat +rabic +rabis +raced +races +rache +racks +racon +radge +radix +radon +raffs +rafts +ragas +ragde +raged +ragee +rager +rages +ragga +raggs +raggy +ragis +ragus +rahed +rahui +raias +raids +raiks +raile +rails +raine +rains +raird +raita +raits +rajas +rajes +raked +rakee +raker +rakes +rakia +rakis +rakus +rales +ramal +ramee +ramet +ramie +ramin +ramis +rammy +ramps +ramus +ranas +rance +rands +ranee +ranga +rangi +rangs +rangy +ranid +ranis +ranke +ranks +rants +raped +raper +rapes +raphe +rappe +rared +raree +rares +rarks +rased +raser +rases +rasps +rasse +rasta +ratal +ratan +ratas +ratch +rated +ratel +rater +rates +ratha +rathe +raths +ratoo +ratos +ratus +rauns +raupo +raved +ravel +raver +raves +ravey +ravin +rawer +rawin +rawly +rawns +raxed +raxes +rayah +rayas +rayed +rayle +rayne +razed +razee +razer +razes +razoo +readd +reads +reais +reaks +realo +reals +reame +reams +reamy +reans +reaps +rears +reast +reata +reate +reave +rebbe +rebec +rebid +rebit +rebop +rebuy +recal +recce +recco +reccy +recit +recks +recon +recta +recti +recto +redan +redds +reddy +reded +redes +redia +redid +redip +redly +redon +redos +redox +redry +redub +redux +redye +reech +reede +reeds +reefs +reefy +reeks +reeky +reels +reens +reest +reeve +refed +refel +reffo +refis +refix +refly +refry +regar +reges +reggo +regie +regma +regna +regos +regur +rehem +reifs +reify +reiki +reiks +reink +reins +reird +reist +reive +rejig +rejon +reked +rekes +rekey +relet +relie +relit +rello +reman +remap +remen +remet +remex +remix +renay +rends +reney +renga +renig +renin +renne +renos +rente +rents +reoil +reorg +repeg +repin +repla +repos +repot +repps +repro +reran +rerig +resat +resaw +resay +resee +reses +resew +resid +resit +resod +resow +resto +rests +resty +resus +retag +retax +retem +retia +retie +retox +revet +revie +rewan +rewax +rewed +rewet +rewin +rewon +rewth +rexes +rezes +rheas +rheme +rheum +rhies +rhime +rhine +rhody +rhomb +rhone +rhumb +rhyne +rhyta +riads +rials +riant +riata +ribas +ribby +ribes +riced +ricer +rices +ricey +richt +ricin +ricks +rides +ridgy +ridic +riels +riems +rieve +rifer +riffs +rifte +rifts +rifty +riggs +rigol +riled +riles +riley +rille +rills +rimae +rimed +rimer +rimes +rimus +rinds +rindy +rines +rings +rinks +rioja +riots +riped +ripes +ripps +rises +rishi +risks +risps +risus +rites +ritts +ritzy +rivas +rived +rivel +riven +rives +riyal +rizas +roads +roams +roans +roars +roary +roate +robed +robes +roble +rocks +roded +rodes +roguy +rohes +roids +roils +roily +roins +roist +rojak +rojis +roked +roker +rokes +rolag +roles +rolfs +rolls +romal +roman +romeo +romps +ronde +rondo +roneo +rones +ronin +ronne +ronte +ronts +roods +roofs +roofy +rooks +rooky +rooms +roons +roops +roopy +roosa +roose +roots +rooty +roped +roper +ropes +ropey +roque +roral +rores +roric +rorid +rorie +rorts +rorty +rosed +roses +roset +roshi +rosin +rosit +rosti +rosts +rotal +rotan +rotas +rotch +roted +rotes +rotis +rotls +roton +rotos +rotte +rouen +roues +roule +rouls +roums +roups +roupy +roust +routh +routs +roved +roven +roves +rowan +rowed +rowel +rowen +rowie +rowme +rownd +rowth +rowts +royne +royst +rozet +rozit +ruana +rubai +rubby +rubel +rubes +rubin +ruble +rubli +rubus +ruche +rucks +rudas +rudds +rudes +rudie +rudis +rueda +ruers +ruffe +ruffs +rugae +rugal +ruggy +ruing +ruins +rukhs +ruled +rules +rumal +rumbo +rumen +rumes +rumly +rummy +rumpo +rumps +rumpy +runch +runds +runed +runes +rungs +runic +runny +runts +runty +rupia +rurps +rurus +rusas +ruses +rushy +rusks +rusma +russe +rusts +ruths +rutin +rutty +ryals +rybat +ryked +rykes +rymme +rynds +ryots +ryper +saags +sabal +sabed +saber +sabes +sabha +sabin +sabir +sable +sabot +sabra +sabre +sacks +sacra +saddo +sades +sadhe +sadhu +sadis +sados +sadza +safed +safes +sagas +sager +sages +saggy +sagos +sagum +saheb +sahib +saice +saick +saics +saids +saiga +sails +saims +saine +sains +sairs +saist +saith +sajou +sakai +saker +sakes +sakia +sakis +sakti +salal +salat +salep +sales +salet +salic +salix +salle +salmi +salol +salop +salpa +salps +salse +salto +salts +salue +salut +saman +samas +samba +sambo +samek +samel +samen +sames +samey +samfu +sammy +sampi +samps +sands +saned +sanes +sanga +sangh +sango +sangs +sanko +sansa +santo +sants +saola +sapan +sapid +sapor +saran +sards +sared +saree +sarge +sargo +sarin +saris +sarks +sarky +sarod +saros +sarus +saser +sasin +sasse +satai +satay +sated +satem +sates +satis +sauba +sauch +saugh +sauls +sault +saunt +saury +sauts +saved +saver +saves +savey +savin +sawah +sawed +sawer +saxes +sayed +sayer +sayid +sayne +sayon +sayst +sazes +scabs +scads +scaff +scags +scail +scala +scall +scams +scand +scans +scapa +scape +scapi +scarp +scars +scart +scath +scats +scatt +scaud +scaup +scaur +scaws +sceat +scena +scend +schav +schmo +schul +schwa +sclim +scody +scogs +scoog +scoot +scopa +scops +scots +scoug +scoup +scowp +scows +scrab +scrae +scrag +scran +scrat +scraw +scray +scrim +scrip +scrob +scrod +scrog +scrow +scudi +scudo +scuds +scuff +scuft +scugs +sculk +scull +sculp +sculs +scums +scups +scurf +scurs +scuse +scuta +scute +scuts +scuzz +scyes +sdayn +sdein +seals +seame +seams +seamy +seans +seare +sears +sease +seats +seaze +sebum +secco +sechs +sects +seder +sedes +sedge +sedgy +sedum +seeds +seeks +seeld +seels +seely +seems +seeps +seepy +seers +sefer +segar +segni +segno +segol +segos +sehri +seifs +seils +seine +seirs +seise +seism +seity +seiza +sekos +sekts +selah +seles +selfs +sella +selle +sells +selva +semee +semes +semie +semis +senas +sends +senes +sengi +senna +senor +sensa +sensi +sente +senti +sents +senvy +senza +sepad +sepal +sepic +sepoy +septa +septs +serac +serai +seral +sered +serer +seres +serfs +serge +seric +serin +serks +seron +serow +serra +serre +serrs +serry +servo +sesey +sessa +setae +setal +seton +setts +sewan +sewar +sewed +sewel +sewen +sewin +sexed +sexer +sexes +sexto +sexts +seyen +shads +shags +shahs +shako +shakt +shalm +shaly +shama +shams +shand +shans +shaps +sharn +shash +shaul +shawm +shawn +shaws +shaya +shays +shchi +sheaf +sheal +sheas +sheds +sheel +shend +shent +sheol +sherd +shere +shero +shets +sheva +shewn +shews +shiai +shiel +shier +shies +shill +shily +shims +shins +ships +shirr +shirs +shish +shiso +shist +shite +shits +shiur +shiva +shive +shivs +shlep +shlub +shmek +shmoe +shoat +shoed +shoer +shoes +shogi +shogs +shoji +shojo +shola +shool +shoon +shoos +shope +shops +shorl +shote +shots +shott +showd +shows +shoyu +shred +shris +shrow +shtik +shtum +shtup +shule +shuln +shuls +shuns +shura +shute +shuts +shwas +shyer +sials +sibbs +sibyl +sices +sicht +sicko +sicks +sicky +sidas +sided +sider +sides +sidha +sidhe +sidle +sield +siens +sient +sieth +sieur +sifts +sighs +sigil +sigla +signa +signs +sijos +sikas +siker +sikes +silds +siled +silen +siler +siles +silex +silks +sills +silos +silts +silty +silva +simar +simas +simba +simis +simps +simul +sinds +sined +sines +sings +sinhs +sinks +sinky +sinus +siped +sipes +sippy +sired +siree +sires +sirih +siris +siroc +sirra +sirup +sisal +sises +sista +sists +sitar +sited +sites +sithe +sitka +situp +situs +siver +sixer +sixes +sixmo +sixte +sizar +sized +sizel +sizer +sizes +skags +skail +skald +skank +skart +skats +skatt +skaws +skean +skear +skeds +skeed +skeef +skeen +skeer +skees +skeet +skegg +skegs +skein +skelf +skell +skelm +skelp +skene +skens +skeos +skeps +skers +skets +skews +skids +skied +skies +skiey +skimo +skims +skink +skins +skint +skios +skips +skirl +skirr +skite +skits +skive +skivy +sklim +skoal +skody +skoff +skogs +skols +skool +skort +skosh +skran +skrik +skuas +skugs +skyed +skyer +skyey +skyfs +skyre +skyrs +skyte +slabs +slade +slaes +slags +slaid +slake +slams +slane +slank +slaps +slart +slats +slaty +slaws +slays +slebs +sleds +sleer +slews +sleys +slier +slily +slims +slipe +slips +slipt +slish +slits +slive +sloan +slobs +sloes +slogs +sloid +slojd +slomo +sloom +sloot +slops +slopy +slorm +slots +slove +slows +sloyd +slubb +slubs +slued +slues +sluff +slugs +sluit +slums +slurb +slurs +sluse +sluts +slyer +slype +smaak +smaik +smalm +smalt +smarm +smaze +smeek +smees +smeik +smeke +smerk +smews +smirr +smirs +smits +smogs +smoko +smolt +smoor +smoot +smore +smorg +smout +smowt +smugs +smurs +smush +smuts +snabs +snafu +snags +snaps +snarf +snark +snars +snary +snash +snath +snaws +snead +sneap +snebs +sneck +sneds +sneed +snees +snell +snibs +snick +snies +snift +snigs +snips +snipy +snirt +snits +snobs +snods +snoek +snoep +snogs +snoke +snood +snook +snool +snoot +snots +snowk +snows +snubs +snugs +snush +snyes +soaks +soaps +soare +soars +soave +sobas +socas +soces +socko +socks +socle +sodas +soddy +sodic +sodom +sofar +sofas +softa +softs +softy +soger +sohur +soils +soily +sojas +sojus +sokah +soken +sokes +sokol +solah +solan +solas +solde +soldi +soldo +solds +soled +solei +soler +soles +solon +solos +solum +solus +soman +somas +sonce +sonde +sones +songs +sonly +sonne +sonny +sonse +sonsy +sooey +sooks +sooky +soole +sools +sooms +soops +soote +soots +sophs +sophy +sopor +soppy +sopra +soral +soras +sorbo +sorbs +sorda +sordo +sords +sored +soree +sorel +sorer +sores +sorex +sorgo +sorns +sorra +sorta +sorts +sorus +soths +sotol +souce +souct +sough +souks +souls +soums +soups +soupy +sours +souse +souts +sowar +sowce +sowed +sowff +sowfs +sowle +sowls +sowms +sownd +sowne +sowps +sowse +sowth +soyas +soyle +soyuz +sozin +spacy +spado +spaed +spaer +spaes +spags +spahi +spail +spain +spait +spake +spald +spale +spall +spalt +spams +spane +spang +spans +spard +spars +spart +spate +spats +spaul +spawl +spaws +spayd +spays +spaza +spazz +speal +spean +speat +specs +spect +speel +speer +speil +speir +speks +speld +spelk +speos +spets +speug +spews +spewy +spial +spica +spick +spics +spide +spier +spies +spiff +spifs +spiks +spile +spims +spina +spink +spins +spirt +spiry +spits +spitz +spivs +splay +splog +spode +spods +spoom +spoor +spoot +spork +sposh +spots +sprad +sprag +sprat +spred +sprew +sprit +sprod +sprog +sprue +sprug +spuds +spued +spuer +spues +spugs +spule +spume +spumy +spurs +sputa +spyal +spyre +squab +squaw +squeg +squid +squit +squiz +stabs +stade +stags +stagy +staig +stane +stang +staph +staps +starn +starr +stars +stats +staun +staws +stays +stean +stear +stedd +stede +steds +steek +steem +steen +steil +stela +stele +stell +steme +stems +stend +steno +stens +stent +steps +stept +stere +stets +stews +stewy +steys +stich +stied +sties +stilb +stile +stime +stims +stimy +stipa +stipe +stire +stirk +stirp +stirs +stive +stivy +stoae +stoai +stoas +stoat +stobs +stoep +stogy +stoit +stoln +stoma +stond +stong +stonk +stonn +stook +stoor +stope +stops +stopt +stoss +stots +stott +stoun +stoup +stour +stown +stowp +stows +strad +strae +strag +strak +strep +strew +stria +strig +strim +strop +strow +stroy +strum +stubs +stude +studs +stull +stulm +stumm +stums +stuns +stupa +stupe +sture +sturt +styed +styes +styli +stylo +styme +stymy +styre +styte +subah +subas +subby +suber +subha +succi +sucks +sucky +sucre +sudds +sudor +sudsy +suede +suent +suers +suete +suets +suety +sugan +sughs +sugos +suhur +suids +suint +suits +sujee +sukhs +sukuk +sulci +sulfa +sulfo +sulks +sulph +sulus +sumis +summa +sumos +sumph +sumps +sunis +sunks +sunna +sunns +sunup +supes +supra +surah +sural +suras +surat +surds +sured +sures +surfs +surfy +surgy +surra +sused +suses +susus +sutor +sutra +sutta +swabs +swack +swads +swage +swags +swail +swain +swale +swaly +swamy +swang +swank +swans +swaps +swapt +sward +sware +swarf +swart +swats +swayl +sways +sweal +swede +sweed +sweel +sweer +swees +sweir +swelt +swerf +sweys +swies +swigs +swile +swims +swink +swipe +swire +swiss +swith +swits +swive +swizz +swobs +swole +swoln +swops +swopt +swots +swoun +sybbe +sybil +syboe +sybow +sycee +syces +sycon +syens +syker +sykes +sylis +sylph +sylva +symar +synch +syncs +synds +syned +synes +synth +syped +sypes +syphs +syrah +syren +sysop +sythe +syver +taals +taata +taber +tabes +tabid +tabis +tabla +tabor +tabun +tabus +tacan +taces +tacet +tache +tacho +tachs +tacks +tacos +tacts +taels +tafia +taggy +tagma +tahas +tahrs +taiga +taigs +taiko +tails +tains +taira +taish +taits +tajes +takas +takes +takhi +takin +takis +takky +talak +talaq +talar +talas +talcs +talcy +talea +taler +tales +talks +talky +talls +talma +talpa +taluk +talus +tamal +tamed +tames +tamin +tamis +tammy +tamps +tanas +tanga +tangi +tangs +tanhs +tanka +tanks +tanky +tanna +tansy +tanti +tanto +tanty +tapas +taped +tapen +tapes +tapet +tapis +tappa +tapus +taras +tardo +tared +tares +targa +targe +tarns +taroc +tarok +taros +tarps +tarre +tarry +tarsi +tarts +tarty +tasar +tased +taser +tases +tasks +tassa +tasse +tasso +tatar +tater +tates +taths +tatie +tatou +tatts +tatus +taube +tauld +tauon +taupe +tauts +tavah +tavas +taver +tawai +tawas +tawed +tawer +tawie +tawse +tawts +taxed +taxer +taxes +taxis +taxol +taxon +taxor +taxus +tayra +tazza +tazze +teade +teads +teaed +teaks +teals +teams +tears +teats +teaze +techs +techy +tecta +teels +teems +teend +teene +teens +teeny +teers +teffs +teggs +tegua +tegus +tehrs +teiid +teils +teind +teins +telae +telco +teles +telex +telia +telic +tells +telly +teloi +telos +temed +temes +tempi +temps +tempt +temse +tench +tends +tendu +tenes +tenge +tenia +tenne +tenno +tenny +tenon +tents +tenty +tenue +tepal +tepas +tepoy +terai +teras +terce +terek +teres +terfe +terfs +terga +terms +terne +terns +terry +terts +tesla +testa +teste +tests +tetes +teths +tetra +tetri +teuch +teugh +tewed +tewel +tewit +texas +texes +texts +thack +thagi +thaim +thale +thali +thana +thane +thang +thans +thanx +tharm +thars +thaws +thawy +thebe +theca +theed +theek +thees +thegn +theic +thein +thelf +thema +thens +theow +therm +thesp +thete +thews +thewy +thigs +thilk +thill +thine +thins +thiol +thirl +thoft +thole +tholi +thoro +thorp +thous +thowl +thrae +thraw +thrid +thrip +throe +thuds +thugs +thuja +thunk +thurl +thuya +thymi +thymy +tians +tiars +tical +ticca +ticed +tices +tichy +ticks +ticky +tiddy +tided +tides +tiers +tiffs +tifos +tifts +tiges +tigon +tikas +tikes +tikis +tikka +tilak +tiled +tiler +tiles +tills +tilly +tilth +tilts +timbo +timed +times +timon +timps +tinas +tinct +tinds +tinea +tined +tines +tinge +tings +tinks +tinny +tints +tinty +tipis +tippy +tired +tires +tirls +tiros +tirrs +titch +titer +titis +titre +titty +titup +tiyin +tiyns +tizes +tizzy +toads +toady +toaze +tocks +tocky +tocos +todde +toeas +toffs +toffy +tofts +tofus +togae +togas +toged +toges +togue +tohos +toile +toils +toing +toise +toits +tokay +toked +toker +tokes +tokos +tolan +tolar +tolas +toled +toles +tolls +tolly +tolts +tolus +tolyl +toman +tombs +tomes +tomia +tommy +tomos +tondi +tondo +toned +toner +tones +toney +tongs +tonka +tonks +tonne +tonus +tools +tooms +toons +toots +toped +topee +topek +toper +topes +tophe +tophi +tophs +topis +topoi +topos +toppy +toque +torah +toran +toras +torcs +tores +toric +torii +toros +torot +torrs +torse +torsi +torsk +torta +torte +torts +tosas +tosed +toses +toshy +tossy +toted +toter +totes +totty +touks +touns +tours +touse +tousy +touts +touze +touzy +towed +towie +towns +towny +towse +towsy +towts +towze +towzy +toyed +toyer +toyon +toyos +tozed +tozes +tozie +trabs +trads +tragi +traik +trams +trank +tranq +trans +trant +trape +traps +trapt +trass +trats +tratt +trave +trayf +trays +treck +treed +treen +trees +trefa +treif +treks +trema +trems +tress +trest +trets +trews +treyf +treys +triac +tride +trier +tries +triff +trigo +trigs +trike +trild +trill +trims +trine +trins +triol +trior +trios +trips +tripy +trist +troad +troak +troat +trock +trode +trods +trogs +trois +troke +tromp +trona +tronc +trone +tronk +trons +trooz +troth +trots +trows +troys +trued +trues +trugo +trugs +trull +tryer +tryke +tryma +tryps +tsade +tsadi +tsars +tsked +tsuba +tsubo +tuans +tuart +tuath +tubae +tubar +tubas +tubby +tubed +tubes +tucks +tufas +tuffe +tuffs +tufts +tufty +tugra +tuile +tuina +tuism +tuktu +tules +tulpa +tulsi +tumid +tummy +tumps +tumpy +tunas +tunds +tuned +tuner +tunes +tungs +tunny +tupek +tupik +tuple +tuque +turds +turfs +turfy +turks +turme +turms +turns +turnt +turps +turrs +tushy +tusks +tusky +tutee +tutti +tutty +tutus +tuxes +tuyer +twaes +twain +twals +twank +twats +tways +tweel +tween +tweep +tweer +twerk +twerp +twier +twigs +twill +twilt +twink +twins +twiny +twire +twirp +twite +twits +twoer +twyer +tyees +tyers +tyiyn +tykes +tyler +tymps +tynde +tyned +tynes +typal +typed +types +typey +typic +typos +typps +typto +tyran +tyred +tyres +tyros +tythe +tzars +udals +udons +ugali +ugged +uhlan +uhuru +ukase +ulama +ulans +ulema +ulmin +ulnad +ulnae +ulnar +ulnas +ulpan +ulvas +ulyie +ulzie +umami +umbel +umber +umble +umbos +umbre +umiac +umiak +umiaq +ummah +ummas +ummed +umped +umphs +umpie +umpty +umrah +umras +unais +unapt +unarm +unary +unaus +unbag +unban +unbar +unbed +unbid +unbox +uncap +unces +uncia +uncos +uncoy +uncus +undam +undee +undos +undug +uneth +unfix +ungag +unget +ungod +ungot +ungum +unhat +unhip +unica +units +unjam +unked +unket +unkid +unlaw +unlay +unled +unlet +unlid +unman +unmew +unmix +unpay +unpeg +unpen +unpin +unred +unrid +unrig +unrip +unsaw +unsay +unsee +unsew +unsex +unsod +untax +untin +unwet +unwit +unwon +upbow +upbye +updos +updry +upend +upjet +uplay +upled +uplit +upped +upran +uprun +upsee +upsey +uptak +upter +uptie +uraei +urali +uraos +urare +urari +urase +urate +urbex +urbia +urdee +ureal +ureas +uredo +ureic +urena +urent +urged +urger +urges +urial +urite +urman +urnal +urned +urped +ursae +ursid +urson +urubu +urvas +users +usnea +usque +usure +usury +uteri +uveal +uveas +uvula +vacua +vaded +vades +vagal +vagus +vails +vaire +vairs +vairy +vakas +vakil +vales +valis +valse +vamps +vampy +vanda +vaned +vanes +vangs +vants +vaped +vaper +vapes +varan +varas +vardy +varec +vares +varia +varix +varna +varus +varve +vasal +vases +vasts +vasty +vatic +vatus +vauch +vaute +vauts +vawte +vaxes +veale +veals +vealy +veena +veeps +veers +veery +vegas +veges +vegie +vegos +vehme +veils +veily +veins +veiny +velar +velds +veldt +veles +vells +velum +venae +venal +vends +vendu +veney +venge +venin +vents +venus +verbs +verra +verry +verst +verts +vertu +vespa +vesta +vests +vetch +vexed +vexer +vexes +vexil +vezir +vials +viand +vibes +vibex +vibey +viced +vices +vichy +viers +views +viewy +vifda +viffs +vigas +vigia +vilde +viler +villi +vills +vimen +vinal +vinas +vinca +vined +viner +vines +vinew +vinic +vinos +vints +viold +viols +vired +vireo +vires +virga +virge +virid +virls +virtu +visas +vised +vises +visie +visne +vison +visto +vitae +vitas +vitex +vitro +vitta +vivas +vivat +vivda +viver +vives +vizir +vizor +vleis +vlies +vlogs +voars +vocab +voces +voddy +vodou +vodun +voema +vogie +voids +voile +voips +volae +volar +voled +voles +volet +volks +volta +volte +volti +volts +volva +volve +vomer +voted +votes +vouge +voulu +vowed +vower +voxel +vozhd +vraic +vrils +vroom +vrous +vrouw +vrows +vuggs +vuggy +vughs +vughy +vulgo +vulns +vulva +vutty +waacs +wacke +wacko +wacks +wadds +waddy +waded +wader +wades +wadge +wadis +wadts +waffs +wafts +waged +wages +wagga +wagyu +wahoo +waide +waifs +waift +wails +wains +wairs +waite +waits +wakas +waked +waken +waker +wakes +wakfs +waldo +walds +waled +waler +wales +walie +walis +walks +walla +walls +wally +walty +wamed +wames +wamus +wands +waned +wanes +waney +wangs +wanks +wanky +wanle +wanly +wanna +wants +wanty +wanze +waqfs +warbs +warby +wards +wared +wares +warez +warks +warms +warns +warps +warre +warst +warts +wases +washy +wasms +wasps +waspy +wasts +watap +watts +wauff +waugh +wauks +waulk +wauls +waurs +waved +waves +wavey +wawas +wawes +wawls +waxed +waxer +waxes +wayed +wazir +wazoo +weald +weals +weamb +weans +wears +webby +weber +wecht +wedel +wedgy +weeds +weeke +weeks +weels +weems +weens +weeny +weeps +weepy +weest +weete +weets +wefte +wefts +weids +weils +weirs +weise +weize +wekas +welds +welke +welks +welkt +wells +welly +welts +wembs +wends +wenge +wenny +wents +weros +wersh +wests +wetas +wetly +wexed +wexes +whamo +whams +whang +whaps +whare +whata +whats +whaup +whaur +wheal +whear +wheen +wheep +wheft +whelk +whelm +whens +whets +whews +wheys +whids +whift +whigs +whilk +whims +whins +whios +whips +whipt +whirr +whirs +whish +whiss +whist +whits +whity +whizz +whomp +whoof +whoot +whops +whore +whorl +whort +whoso +whows +whump +whups +whyda +wicca +wicks +wicky +widdy +wides +wiels +wifed +wifes +wifey +wifie +wifty +wigan +wigga +wiggy +wikis +wilco +wilds +wiled +wiles +wilga +wilis +wilja +wills +wilts +wimps +winds +wined +wines +winey +winge +wings +wingy +winks +winna +winns +winos +winze +wiped +wiper +wipes +wired +wirer +wires +wirra +wised +wises +wisha +wisht +wisps +wists +witan +wited +wites +withe +withs +withy +wived +wiver +wives +wizen +wizes +woads +woald +wocks +wodge +woful +wojus +woker +wokka +wolds +wolfs +wolly +wolve +wombs +womby +womyn +wonga +wongi +wonks +wonky +wonts +woods +wooed +woofs +woofy +woold +wools +woons +woops +woopy +woose +woosh +wootz +words +works +worms +wormy +worts +wowed +wowee +woxen +wrang +wraps +wrapt +wrast +wrate +wrawl +wrens +wrick +wried +wrier +wries +writs +wroke +wroot +wroth +wryer +wuddy +wudus +wulls +wurst +wuses +wushu +wussy +wuxia +wyled +wyles +wynds +wynns +wyted +wytes +xebec +xenia +xenic +xenon +xeric +xerox +xerus +xoana +xrays +xylan +xylem +xylic +xylol +xylyl +xysti +xysts +yaars +yabas +yabba +yabby +yacca +yacka +yacks +yaffs +yager +yages +yagis +yahoo +yaird +yakka +yakow +yales +yamen +yampy +yamun +yangs +yanks +yapok +yapon +yapps +yappy +yarak +yarco +yards +yarer +yarfa +yarks +yarns +yarrs +yarta +yarto +yates +yauds +yauld +yaups +yawed +yawey +yawls +yawns +yawny +yawps +ybore +yclad +ycled +ycond +ydrad +ydred +yeads +yeahs +yealm +yeans +yeard +years +yecch +yechs +yechy +yedes +yeeds +yeesh +yeggs +yelks +yells +yelms +yelps +yelts +yenta +yente +yerba +yerds +yerks +yeses +yesks +yests +yesty +yetis +yetts +yeuks +yeuky +yeven +yeves +yewen +yexed +yexes +yfere +yiked +yikes +yills +yince +yipes +yippy +yirds +yirks +yirrs +yirth +yites +yitie +ylems +ylike +ylkes +ymolt +ympes +yobbo +yobby +yocks +yodel +yodhs +yodle +yogas +yogee +yoghs +yogic +yogin +yogis +yoick +yojan +yoked +yokel +yoker +yokes +yokul +yolks +yolky +yomim +yomps +yonic +yonis +yonks +yoofs +yoops +yores +yorks +yorps +youks +yourn +yours +yourt +youse +yowed +yowes +yowie +yowls +yowza +yrapt +yrent +yrivd +yrneh +ysame +ytost +yuans +yucas +yucca +yucch +yucko +yucks +yucky +yufts +yugas +yuked +yukes +yukky +yukos +yulan +yules +yummo +yummy +yumps +yupon +yuppy +yurta +yurts +yuzus +zabra +zacks +zaida +zaidy +zaire +zakat +zaman +zambo +zamia +zanja +zante +zanza +zanze +zappy +zarfs +zaris +zatis +zaxes +zayin +zazen +zeals +zebec +zebub +zebus +zedas +zeins +zendo +zerda +zerks +zeros +zests +zetas +zexes +zezes +zhomo +zibet +ziffs +zigan +zilas +zilch +zilla +zills +zimbi +zimbs +zinco +zincs +zincy +zineb +zines +zings +zingy +zinke +zinky +zippo +zippy +ziram +zitis +zizel +zizit +zlote +zloty +zoaea +zobos +zobus +zocco +zoeae +zoeal +zoeas +zoism +zoist +zombi +zonae +zonda +zoned +zoner +zones +zonks +zooea +zooey +zooid +zooks +zooms +zoons +zooty +zoppa +zoppo +zoril +zoris +zorro +zouks +zowee +zowie +zulus +zupan +zupas +zuppa +zurfs +zuzim +zygal +zygon +zymes +zymic \ No newline at end of file diff --git a/wordle_solver/game.py b/wordle_solver/game.py new file mode 100644 index 0000000..a2d188f --- /dev/null +++ b/wordle_solver/game.py @@ -0,0 +1,61 @@ +"""Feedback simulation matching Wordle's own coloring algorithm.""" + +from enum import IntEnum + + +class Clue(IntEnum): + GREY = 0 + YELLOW = 1 + GREEN = 2 + + +CLUE_CHARS = {Clue.GREEN: "G", Clue.YELLOW: "Y", Clue.GREY: "B"} + +# Accept a few common shorthand alphabets when parsing user input. +_CHAR_TO_CLUE = { + "G": Clue.GREEN, "2": Clue.GREEN, + "Y": Clue.YELLOW, "1": Clue.YELLOW, + "B": Clue.GREY, "0": Clue.GREY, ".": Clue.GREY, "-": Clue.GREY, +} + + +def score_guess(guess: str, answer: str) -> tuple: + """Return the clue Wordle would show for `guess` against the true `answer`. + + Two-pass algorithm: greens first, then yellows against leftover letters, + so duplicate letters are handled the same way the real game does. + """ + n = len(guess) + result = [Clue.GREY] * n + remaining = list(answer) + + for i in range(n): + if guess[i] == remaining[i]: + result[i] = Clue.GREEN + remaining[i] = None + + for i in range(n): + if result[i] == Clue.GREEN: + continue + letter = guess[i] + if letter in remaining: + result[i] = Clue.YELLOW + remaining[remaining.index(letter)] = None + + return tuple(result) + + +def pattern_to_str(pattern) -> str: + return "".join(CLUE_CHARS[c] for c in pattern) + + +def pattern_to_digits(pattern) -> str: + return "".join(str(int(c)) for c in pattern) + + +def str_to_pattern(s: str) -> tuple: + s = s.strip() + try: + return tuple(_CHAR_TO_CLUE[ch.upper()] for ch in s) + except KeyError as e: + raise ValueError(f"Unrecognized clue character: {e.args[0]!r}") from None diff --git a/wordle_solver/solver.py b/wordle_solver/solver.py new file mode 100644 index 0000000..9bea4f5 --- /dev/null +++ b/wordle_solver/solver.py @@ -0,0 +1,122 @@ +"""Candidate tracking and a frequency/positional heuristic for ranking guesses.""" + +from collections import Counter +from dataclasses import dataclass, field + +from .game import Clue, score_guess + +WORD_LEN = 5 +MAX_GUESSES = 6 + + +@dataclass +class GuessRecord: + guess: str + pattern: tuple + + +@dataclass +class Solver: + answers: list + extra_guesses: list + history: list = field(default_factory=list) + candidates: list = field(init=False) + + def __post_init__(self): + self.candidates = list(self.answers) + + @property + def all_words(self) -> list: + return self.answers + self.extra_guesses + + def apply(self, guess: str, pattern: tuple) -> None: + """Record a guess/result and narrow the remaining candidates to those + consistent with it (by literally re-simulating Wordle's own coloring).""" + guess = guess.lower() + self.history.append(GuessRecord(guess, pattern)) + self.candidates = [w for w in self.candidates if score_guess(guess, w) == pattern] + + def reset(self) -> None: + self.history.clear() + self.candidates = list(self.answers) + + def is_solved(self) -> bool: + return bool(self.history) and self.history[-1].pattern == (Clue.GREEN,) * WORD_LEN + + def hard_mode_constraints(self): + """Derive the two hard-mode requirements from history so far: + fixed green letters by position, and minimum required count per + letter from any green/yellow marks seen.""" + green = {} + min_count = Counter() + for rec in self.history: + marks_this_guess = Counter() + for i, (ch, clue) in enumerate(zip(rec.guess, rec.pattern)): + if clue == Clue.GREEN: + green[i] = ch + marks_this_guess[ch] += 1 + elif clue == Clue.YELLOW: + marks_this_guess[ch] += 1 + for ch, count in marks_this_guess.items(): + if count > min_count[ch]: + min_count[ch] = count + return green, min_count + + def hard_mode_pool(self) -> list: + """Every known word that is a *legal* next guess under hard-mode rules: + green letters stay in place, and every yellow/green letter seen so far + appears at least as many times as it has been confirmed.""" + if not self.history: + return list(self.all_words) + + green, min_count = self.hard_mode_constraints() + pool = [] + for w in self.all_words: + if any(w[i] != ch for i, ch in green.items()): + continue + counts = Counter(w) + if any(counts[ch] < need for ch, need in min_count.items()): + continue + pool.append(w) + return pool + + +def letter_stats(words: list): + """Per-position and overall-presence letter frequencies across `words`.""" + n = len(words) + position_freq = [Counter() for _ in range(WORD_LEN)] + presence_freq = Counter() + for w in words: + for i, ch in enumerate(w): + position_freq[i][ch] += 1 + for ch in set(w): + presence_freq[ch] += 1 + position_freq = [{ch: c / n for ch, c in pf.items()} for pf in position_freq] + presence_freq = {ch: c / n for ch, c in presence_freq.items()} + return position_freq, presence_freq + + +def score_word(word, position_freq, presence_freq, position_weight=1.0, presence_weight=1.0, repeat_penalty=0.85): + """Higher score = letters that are both common overall and likely in this + position, favoring new letters over repeats since repeats teach us less.""" + score = 0.0 + seen = set() + for i, ch in enumerate(word): + score += position_weight * position_freq[i].get(ch, 0.0) + gain = presence_weight * presence_freq.get(ch, 0.0) + score += gain if ch not in seen else -repeat_penalty * gain + seen.add(ch) + return score + + +def rank_guesses(pool, candidates, top_n=10, position_weight=1.0, presence_weight=1.0): + """Rank `pool` words by the heuristic, computed from letter stats over the + still-possible `candidates`. Returns (word, score, is_possible_answer).""" + position_freq, presence_freq = letter_stats(candidates) + candidate_set = set(candidates) + scored = [ + (score_word(w, position_freq, presence_freq, position_weight, presence_weight), w) + for w in pool + ] + scored.sort(key=lambda pair: (-pair[0], pair[1])) + return [(w, s, w in candidate_set) for s, w in scored[:top_n]] diff --git a/wordle_solver/wager.py b/wordle_solver/wager.py new file mode 100644 index 0000000..88e2f36 --- /dev/null +++ b/wordle_solver/wager.py @@ -0,0 +1,39 @@ +"""Tracks a $-per-letter wager score alongside the solver. + +Default rule: $1 per correct-spot letter, $2 per present-but-wrong-spot +letter, $3 per absent letter — tune with the `/price` command if your +wager uses different numbers. +""" + +from dataclasses import dataclass, field + +from .game import Clue + +DEFAULT_PRICES = {Clue.GREEN: 1, Clue.YELLOW: 2, Clue.GREY: 3} + + +@dataclass +class Wager: + prices: dict = field(default_factory=lambda: dict(DEFAULT_PRICES)) + round_total: int = 0 + session_total: int = 0 + + def cost_of(self, pattern) -> int: + return sum(self.prices[clue] for clue in pattern) + + def add(self, pattern) -> int: + cost = self.cost_of(pattern) + self.round_total += cost + self.session_total += cost + return cost + + def new_round(self) -> None: + self.round_total = 0 + + def set_prices(self, green: int, yellow: int, grey: int) -> None: + self.prices = {Clue.GREEN: green, Clue.YELLOW: yellow, Clue.GREY: grey} + + def prices_str(self) -> str: + return (f"correct=${self.prices[Clue.GREEN]} " + f"present=${self.prices[Clue.YELLOW]} " + f"absent=${self.prices[Clue.GREY]}") diff --git a/wordle_solver/words.py b/wordle_solver/words.py new file mode 100644 index 0000000..029bd11 --- /dev/null +++ b/wordle_solver/words.py @@ -0,0 +1,27 @@ +"""Loading of the bundled word lists. + +Both files come from the original NYT Wordle source: `answers.txt` is the +2,315-word possible-answer list, `guesses.txt` is the additional ~10,657 +words accepted as valid guesses but never used as answers. +""" + +from pathlib import Path + +DATA_DIR = Path(__file__).parent / "data" + + +def _load(filename: str) -> list: + path = DATA_DIR / filename + return [w.strip().lower() for w in path.read_text().splitlines() if w.strip()] + + +def load_answers() -> list: + return _load("answers.txt") + + +def load_extra_guesses() -> list: + return _load("guesses.txt") + + +def load_all_valid_words() -> list: + return load_answers() + load_extra_guesses()