From 25cc42619c9f4381df45d84f5188dba290c3cfaa Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Thu, 13 Oct 2022 09:45:15 -0700 Subject: [PATCH] Add some example code. --- examples/README | 2 + examples/pyskel/pyskel.py | 25 + examples/reminder/.reminder | 72 + examples/reminder/reminder.py | 280 + examples/scrabble/scrabble.py | 162 + examples/wordle/wordle.py | 1597 +++ examples/wordle/wordle_guesses.txt | 12972 +++++++++++++++++++++++++ examples/wordle/wordle_hash.txt | 611 ++ examples/wordle/wordle_solutions.txt | 2315 +++++ 9 files changed, 18036 insertions(+) create mode 100644 examples/README create mode 100755 examples/pyskel/pyskel.py create mode 100644 examples/reminder/.reminder create mode 100755 examples/reminder/reminder.py create mode 100755 examples/scrabble/scrabble.py create mode 100755 examples/wordle/wordle.py create mode 100644 examples/wordle/wordle_guesses.txt create mode 100644 examples/wordle/wordle_hash.txt create mode 100644 examples/wordle/wordle_solutions.txt diff --git a/examples/README b/examples/README new file mode 100644 index 0000000..5d02a87 --- /dev/null +++ b/examples/README @@ -0,0 +1,2 @@ +Stuff under here is example code that uses pyutils library routines and +is meant to just be illustrative and fun. diff --git a/examples/pyskel/pyskel.py b/examples/pyskel/pyskel.py new file mode 100755 index 0000000..effd20a --- /dev/null +++ b/examples/pyskel/pyskel.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +"""The start of something cool... + +This is a skeleton python script that I keep around and use as the +start of any new utility that I'm working on. +""" + +import logging +from typing import Optional + +from pyutils import bootstrap, config + +logger = logging.getLogger(__name__) +args = config.add_commandline_args(f'({__file__})', f'Args related to {__file__}') + + +@bootstrap.initialize +def main() -> Optional[int]: + print('Hello world.') + return None + + +if __name__ == '__main__': + main() diff --git a/examples/reminder/.reminder b/examples/reminder/.reminder new file mode 100644 index 0000000..cf4c33a --- /dev/null +++ b/examples/reminder/.reminder @@ -0,0 +1,72 @@ +# +# Anniversaries +# +type=anniversary +Your Anniversary=aug 31 2003 + +# +# Birthdays +# +type=birthday +Your birthday=apr 15 1974 + +# +# Holidays +# +type=event +TGIF=this friday at 5:00p +Christmas Eve=christmas eve +Christmas=christmas +Thomas Jefferson's Birthday=apr 13 +Advent Starts=christmas -4 sunday +New Year's Day=new year's day +New Year's Eve=new year's eve +Martin Luther King Day=mlk day +Presidents' Day=presidents' day +Armed Forces Day=3rd sat in may +Memorial Day=memorial day +Flag Day=jun 14 +Cinco de Mayo=may 5 +Independence Day=independence day +Labor Day=labor day +Columbus Day=columbus day +Veterans Day=veterans' day +Thanksgiving Day=thanksgiving +Tax Day=april 15 +Arbor Day=2 wed in apr +Groundhog Day=2/2 +Valentine's Day=feb 14 +St. Patrick's Day=mar 17 +April Fools Day=apr 1 +Earth Day=apr 22 +Halloween=oct 31 +Daylight Saving Time Begins=2 sun in mar +Daylight Saving Time Ends=1 sun in nov +Mothers' Day=2 sun in may +Fathers' Day=3 sun in june +Easter=easter +Start of Lent=easter -40 days +Good Friday=easter -2 days +Palm Sunday=easter -7 days +Ash Wednesday=easter -46 days +Shrove Tuesday / Mardi Gras=easter -47 days +Ascension=easter +39 days +Pentecost=easter +49 days +Winter Solstice=dec 21 +Summer Solstice=jun 21 +Vernal Equinox=mar 20 +Autumnal Equinox=sept 22 +St. Andrew's Day=nov 30 +National Talk-Like-A-Pirate Day=sept 19 +May Day=may 1 +Pi Day=3/14 +Albert Einstein's Birthday=3/14 +International Cannabis Day=4/20 +No Pants Day=1st fri in may +Ask A Stupid Question Day=sep 28 +October Fool's Day=oct 1 +National Catfish Day=june 25 +Parent's Day=4th sat in july +National Aviation Day=aug 19 +International Women's Day=mar 8 +Election Day=1 tue of nov diff --git a/examples/reminder/reminder.py b/examples/reminder/reminder.py new file mode 100755 index 0000000..23c127d --- /dev/null +++ b/examples/reminder/reminder.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python3 + +""" +Reminders for upcoming important dates. +""" + +import datetime +import logging +import re +import sys +from collections import defaultdict +from typing import Dict, List, Optional + +from pyutils import argparse_utils, bootstrap, config, persistent, string_utils +from pyutils.ansi import fg, reset +from pyutils.datetimez import dateparse_utils as dateparse +from pyutils.files import file_utils + +logger = logging.getLogger(__name__) +cfg = config.add_commandline_args( + f"Main ({__file__})", "Reminder of events, birthdays and anniversaries." +) +cfg.add_argument( + "--reminder_filename", + type=argparse_utils.valid_filename, + default='.reminder', + metavar='FILENAME', + help="Override the .reminder filepath", +) +cfg.add_argument( + '--reminder_cache_file', + type=str, + default='.reminder_cache', + metavar='FILENAME', + help='Override the .reminder cache location', +) +cfg.add_argument( + "-n", "--count", type=int, metavar='COUNT', help="How many events to remind about" +) +cfg.add_argument( + "--days_ahead", + type=int, + metavar='#DAYS', + help="How many days ahead to remind about", +) +cfg.add_argument( + "-d", + "--date", + "--dates", + action="store_true", + help="Also include the date along with the n day countdown", +) +cfg.add_argument( + "--override_timestamp", + nargs=1, + type=argparse_utils.valid_datetime, + help="Don't use the current datetime, use this one instead.", + metavar="DATE/TIME STRING", + default=None, +) + + +# This decorator handles caching this object's state on disk and feeding the +# state back to new instances of this object at initialization time. It also +# makes sure that this object is a global singleton in the program. +@persistent.persistent_autoloaded_singleton() +class Reminder(object): + MODE_EVENT = 0 + MODE_BIRTHDAY = 1 + MODE_ANNIVERSARY = 2 + + def __init__( + self, cached_state: Optional[Dict[datetime.date, List[str]]] = None + ) -> None: + if not config.config['override_timestamp']: + self.today = datetime.date.today() + else: + self.today = config.config['override_timestamp'][0].date() + logger.debug( + 'Overriding "now" with %s because of commandline argument.', + self.today, + ) + if cached_state is not None: + self.label_by_date = cached_state + return + self.label_by_date: Dict[datetime.date, List[str]] = defaultdict(list) + self.read_file(config.config['reminder_filename']) + + def handle_event_by_adjusting_year_to_now( + self, + parsing_mode: int, + orig_date: datetime.date, + orig_label: str, + saw_overt_year: bool, + ) -> None: + for year in (self.today.year, self.today.year + 1): + label = orig_label + if saw_overt_year: + delta = year - orig_date.year + if parsing_mode == Reminder.MODE_BIRTHDAY: + if delta != 0: + label += f" ({delta} year{string_utils.pluralize(delta)} old)" + elif parsing_mode == Reminder.MODE_ANNIVERSARY: + if delta != 0: + label += f" ({delta}{string_utils.thify(delta)} anniversary)" + dt = datetime.date( + year=year, + month=orig_date.month, + day=orig_date.day, + ) + logger.debug('Date in %d: %s', year, dt) + self.label_by_date[dt].append(label) + logger.debug('%s => %s', dt, label) + + def handle_event_with_fixed_year( + self, + orig_date: datetime.date, + orig_label: str, + ) -> None: + logger.debug('Fixed date event...') + self.label_by_date[orig_date].append(orig_label) + logger.debug('%s => %s', orig_date, orig_label) + + def read_file(self, filename: str) -> None: + logger.debug('Reading %s:', filename) + date_parser = dateparse.DateParser() + parsing_mode = Reminder.MODE_EVENT + with open(filename) as f: + lines = f.readlines() + for line in lines: + line = line.strip() + line = re.sub(r"#.*$", "", line) + if re.match(r"^ *$", line) is not None: + continue + logger.debug('> %s', line) + try: + if "=" in line: + label, date = line.split("=") + else: + print(f"Skipping unparsable line: {line}", file=sys.stderr) + logger.error('Skipping malformed line: %s', line) + continue + + if label == "type": + if "event" in date: + parsing_mode = Reminder.MODE_EVENT + logger.debug('--- EVENT MODE ---') + elif "birthday" in date: + parsing_mode = Reminder.MODE_BIRTHDAY + logger.debug('--- BIRTHDAY MODE ---') + elif "anniversary" in date: + parsing_mode = Reminder.MODE_ANNIVERSARY + logger.debug('--- ANNIVERSARY MODE ---') + else: + date_parser.parse(date) + orig_date = date_parser.get_date() + if orig_date is None: + print(f"Skipping unparsable date: {line}", file=sys.stderr) + logger.error('Skipping line with unparsable date') + continue + logger.debug('Original date: %s', orig_date) + + overt_year = date_parser.saw_overt_year + if parsing_mode in ( + Reminder.MODE_BIRTHDAY, + Reminder.MODE_ANNIVERSARY, + ) or (parsing_mode == Reminder.MODE_EVENT and not overt_year): + self.handle_event_by_adjusting_year_to_now( + parsing_mode, orig_date, label, overt_year + ) + else: + self.handle_event_with_fixed_year(orig_date, label) + + except Exception as e: + print(f"Skipping unparsable line: {line}", file=sys.stderr) + logger.error('Skipping malformed line: %s', line) + logger.exception(e) + + def remind( + self, count: Optional[int], days_ahead: Optional[int], say_date: bool + ) -> None: + need_both = False + if count is not None and days_ahead is not None: + need_both = True + seen = 0 + + for date in sorted(self.label_by_date.keys()): + delta = date - self.today + d = delta.days + if d >= 0: + if days_ahead is not None: + if d > days_ahead: + if not need_both: + return + seen |= 1 + if seen == 3: + return + labels = self.label_by_date[date] + for label in labels: + if d > 1: + if d <= 3: + msg = f"{fg('blaze orange')}{d} days{reset()} until {label}" + elif d <= 7: + msg = f"{fg('peach orange')}{d} days{reset()} until {label}" + else: + msg = f"{d} days until {label}" + elif d == 1: + msg = f"{fg('outrageous orange')}Tomorrow{reset()} is {label}" + else: + assert d == 0 + msg = f"{fg('red')}Today{reset()} is {label}" + if say_date: + msg += f" {fg('battleship gray')}on {date.strftime('%A, %B %-d')}{reset()}" + print(msg) + if count is not None: + count -= 1 + if count <= 0: + if not need_both: + return + seen |= 2 + if seen == 3: + return + + @classmethod + def load(cls): + if not config.config['override_timestamp']: + now = datetime.datetime.now() + else: + now = config.config['override_timestamp'][0] + logger.debug( + 'Overriding "now" with %s because of commandline argument.', now + ) + + cache_ts = file_utils.get_file_mtime_as_datetime( + config.config['reminder_cache_file'] + ) + if cache_ts is None: + return None + + # If the cache was already written today... + if ( + now.day == cache_ts.day + and now.month == cache_ts.month + and now.year == cache_ts.year + ): + reminder_ts = file_utils.get_file_mtime_as_datetime( + config.config['reminder_filename'] + ) + + # ...and the .reminder file wasn't updated since the cache write... + if reminder_ts <= cache_ts: + import pickle + + with open(config.config['reminder_cache_file'], 'rb') as rf: + reminder_data = pickle.load(rf) + return cls(reminder_data) + return None + + def save(self): + import pickle + + with open(config.config['reminder_cache_file'], 'wb') as wf: + pickle.dump( + self.label_by_date, + wf, + pickle.HIGHEST_PROTOCOL, + ) + + +@bootstrap.initialize +def main() -> None: + reminder = Reminder() + count = config.config['count'] + days_ahead = config.config['days_ahead'] + reminder.remind(count, days_ahead, config.config['date']) + return None + + +if __name__ == "__main__": + main() diff --git a/examples/scrabble/scrabble.py b/examples/scrabble/scrabble.py new file mode 100755 index 0000000..82f981e --- /dev/null +++ b/examples/scrabble/scrabble.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 + +import itertools +import logging +import string +import sys +from typing import Set + +from pyutils import bootstrap, config +from pyutils.unscrambler import Unscrambler + +cfg = config.add_commandline_args( + f'Scrabble (aka Wordscapes)! ({__file__})', + 'Find all words in a query letter set (proper and subset based)', +) +cfg.add_argument( + '--min_length', + help='Minimum length permissable in results', + metavar='N', + type=int, + default=1, +) +cfg.add_argument( + '--show_scrabble_score', + help='Should we compute and display Scrabble game scores?', + action='store_true', +) +cfg.add_argument( + '--extra_letters', + help='Set of letters available on the board (not in hand). e.g. --extra_letters s t r', + nargs='*', +) +logger = logging.getLogger(__name__) + + +scrabble_score_by_letter = { + 'a': 1, + 'e': 1, + 'i': 1, + 'l': 1, + 'n': 1, + 'o': 1, + 'r': 1, + 's': 1, + 't': 1, + 'u': 1, + 'd': 2, + 'g': 2, + 'b': 3, + 'c': 3, + 'm': 3, + 'p': 3, + 'f': 4, + 'h': 4, + 'v': 4, + 'w': 4, + 'y': 4, + 'k': 5, + 'j': 8, + 'x': 8, + 'q': 10, + 'z': 10, +} + + +def fill_in_blanks(letters: str, skip: Set[str]) -> str: + if '_' not in letters: + logger.debug('Filled in blanks: %s', letters) + yield letters + return + + for replacement in string.ascii_lowercase: + filled_in = letters.replace('_', replacement, 1) + if filled_in not in skip: + logger.debug( + 'Orig: %s, replacement is %s, new: %s', letters, replacement, filled_in + ) + skip.add(filled_in) + yield from fill_in_blanks(filled_in, skip) + + +def lookup_letter_set( + letters: str, + unscrambler: Unscrambler, + seen_sigs: Set[int], + seen_words: Set[str], +) -> None: + sig = unscrambler.compute_word_sig(letters) + if sig not in seen_sigs: + logger.debug('%s => %s', letters, sig) + for (words, exact) in unscrambler.lookup_by_sig(sig).items(): + if exact: + for word in words.split(','): + if len(word) >= config.config['min_length']: + seen_words.add(word) + else: + logger.debug('Skipping %s because it\'s too short.', word) + seen_sigs.add(sig) + + +@bootstrap.initialize +def main() -> None: + if len(sys.argv) < 2: + print("Missing required query.", file=sys.stderr) + sys.exit(-1) + + seen_sigs: Set[int] = set() + seen_words: Set[str] = set() + seen_fill_ins: Set[str] = set() + u: Unscrambler = Unscrambler() + + query = sys.argv[1].lower() + orig_letters = set([x for x in query if x != '_']) + logger.debug('Initial query: %s (%s)', query, orig_letters) + + if config.config['extra_letters']: + for extra in config.config['extra_letters']: + extra = extra.lower() + query = query + extra + logger.debug('Building with extra letter: %s; query is %s', extra, query) + for q in fill_in_blanks(query, seen_fill_ins): + logger.debug('...blanks filled in: %s', q) + for x in range(config.config['min_length'], len(q) + 1): + for tup in itertools.combinations(q, x): + letters = ''.join(tup) + logger.debug('...considering subset: %s', letters) + lookup_letter_set(letters, u, seen_sigs, seen_words) + query = query[:-1] + logger.debug('Removing extra letter; query is %s', query) + else: + for q in fill_in_blanks(query, seen_fill_ins): + logger.debug('...blanks filled in: %s', q) + for x in range(config.config['min_length'], len(q) + 1): + for tup in itertools.combinations(q, x): + letters = ''.join(tup) + logger.debug('...considering subset: %s', letters) + lookup_letter_set(letters, u, seen_sigs, seen_words) + + output = {} + for word in sorted(seen_words): + if config.config['show_scrabble_score']: + score = 0 + copy = orig_letters.copy() + for letter in word: + if letter in copy: + copy.remove(letter) + score += scrabble_score_by_letter.get(letter, 0) + if len(word) >= 7: + score += 50 + output[word] = score + else: + output[word] = len(word) + + for word, n in sorted(output.items(), key=lambda x: x[1]): + if config.config['show_scrabble_score']: + print(f'{word} => {n}') + else: + print(word) + + +if __name__ == "__main__": + main() diff --git a/examples/wordle/wordle.py b/examples/wordle/wordle.py new file mode 100755 index 0000000..e5b6c6f --- /dev/null +++ b/examples/wordle/wordle.py @@ -0,0 +1,1597 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Wordle! PLAY, AUTOPLAY, CHEAT, PRECOMPUTE and SELFTEST. +""" + +import enum +import hashlib +import logging +import math +import multiprocessing +import random +import re +import string +import sys +import time +from collections import Counter, defaultdict +from typing import Any, Dict, List, NamedTuple, Optional, Set, Tuple + +from pyutils import ansi, bootstrap, config, list_utils, string_utils +from pyutils.collectionz.shared_dict import SharedDict +from pyutils.files import file_utils +from pyutils.parallelize import executors +from pyutils.parallelize import parallelize as par +from pyutils.parallelize import smart_future +from pyutils.typez import histogram + +logger = logging.getLogger(__name__) +args = config.add_commandline_args( + f'Wordle! ({__file__})', + 'Args related to cheating at Wordle.', +) +args.add_argument( + '--mode', + type=str, + default='PLAY', + choices=['CHEAT', 'AUTOPLAY', 'SELFTEST', 'PRECOMPUTE', 'PLAY'], + metavar='MODE', + help="""RAW| +Our mode of operation: + + PLAY = play wordle with me! Pick a random solution or + specify a solution with --template. + + CHEAT = given a --template and, optionally, --letters_in_word + and/or --letters_to_avoid, return the best guess word; + + AUTOPLAY = given a complete word in --template, guess it step + by step showing work; + + SELFTEST = autoplay every possible solution keeping track of + wins/losses and average number of guesses; + +PRECOMPUTE = populate hash table with optimal guesses. + """, +) +args.add_argument( + '--template', + type=str, + help='The current board in PLAY, CHEAT, AUTOPLAY mode. Use _\'s for unknown letters.', +) +args.add_argument( + '--letters_to_avoid', + type=str, + help='In CHEAT mode, the set of letters known to not be in the solution.', + metavar='LETTERS', +) +args.add_argument( + '--letters_in_word', + type=str, + help="""RAW| +Letters known to be in the solution but whose positions are not yet known. + +For example: + + t0i23 => says we tried a 't' as the first letter (0) so we + know it's in the word and not there. We also know + there's an 'i' which is not the middle letter (2) + and is not the 4th letter (3). Note the zero-based + position counting semantics (i.e. the first letter + is letter 0). + e34f0 => mean we know there's an 'e' and an 'f'; we've attempted + former in positions 3-4 (recall, 4 is the last spot in + a standard 5 letter wordle) and the latter in the + first spot (0) already. + """, + metavar='...', +) +args.add_argument( + '--solutions_file', + type=str, + default='/home/scott/bin/wordle_solutions.txt', + help='Where can I find a valid word list for solutions?', +) +args.add_argument( + '--guesses_file', + type=str, + default='/home/scott/bin/wordle_guesses.txt', + help='Where can I find a valid word list for guesses?', +) +args.add_argument( + '--hash_file', + type=str, + default='/home/scott/bin/wordle_hash.txt', + help='Where can I find my precomputed hash file?', +) + +# Type aliases for code readability +Position = int +Letter = str +Word = str +Fprint = str +Bucket = int + + +class Hint(enum.IntFlag): + """Green, yellow or gray?""" + + GRAY_WRONG = 0 + YELLOW_LETTER_RIGHT_POSITION_WRONG = 1 + GREEN_LETTER_IN_RIGHT_POSITION = 2 + + +class WordStateUndoType(enum.IntFlag): + """Used to record guess undo information by type.""" + + LETTER_IN_SOLUTION_MIN_CHANGE = 1 + LETTER_IN_SOLUTION_MAX_CHANGE = 2 + LETTER_IN_SOLUTION_ADDED_WITH_MIN_MAX = 3 + YELLOW_LETTER_ADDED = 4 + GREEN_LETTER_ADDED = 5 + GRAY_LETTER_ADDED = 6 + + +class WordStateUndo(NamedTuple): + """A record per guess containing all the info needed to undo it.""" + + guess: Word + hints: Dict[Position, Hint] + mods: List[Dict[str, Any]] + + +class WordState(object): + """Keeps track of the current board state, previous guesses and hints, + and which letters are known/unknown/eliminated, etc... + + """ + + def __init__( + self, + solution_length: int, + max_letter_population_per_word: Dict[Letter, int], + *, + letters_at_known_positions: Optional[Dict[Position, Letter]] = None, + letters_at_unknown_positions: Optional[Dict[Letter, Set[Position]]] = None, + letters_excluded: Optional[Set[Letter]] = None, + ): + """Initialize the WordState given the length of the solution word + (number of letters), maximum number of times a given letter + may appear in the solution, and, optionally, some letter + restrictions. All positions below are zero-based. + + letters_at_known_positions: position => letter map + letters_at_unknown_positions: letter => set(position(s) tried) map + letters_excluded: set of letters known to not be in the word + + """ + super().__init__() + assert solution_length > 0 + self.solution_length: int = solution_length + + # All info necessary to undo a guess later. We'll add an entry + # for every guess in a stack. + self.undo_info: List[WordStateUndo] = [] + + # We're going to use internal methods to set up the initial + # state and they all require an undo record to populate... but + # there's no initial guess and we'll never undo beyond here. + # So create a fake undo record for them to scribble on and + # throw it away later. + fake_undo: WordStateUndo = WordStateUndo( + guess="fake, will be thrown away", + hints={}, + mods=[], + ) + + # Across all solutions, how many times did each letter appear + # per word, at max. For each letter we learn is in the word + # we'll track a min..max valid occurrances; this is the + # initial max. It's the max times a given letter appears in + # any word in the solution set. + assert max_letter_population_per_word + self.max_letter_population_per_word = max_letter_population_per_word + + # The min..max population for every letter we know in the solution. + # The List[int] here has two entries: min and max. + self.letters_in_solution: Dict[Letter, List[int]] = {} + + # Green letters by where they are. + self.letters_at_known_positions: Dict[Position, Letter] = {} + if letters_at_known_positions is not None: + for n, letter in letters_at_known_positions.items(): + self.record_green(n, letter, fake_undo) + + # Yellow letters to where we've already tried them (i.e. where + # the cannot be.) + self.letters_at_unknown_positions: Dict[Letter, Set[Position]] = defaultdict( + set + ) + if letters_at_unknown_positions is not None: + for letter, tried_pos in letters_at_unknown_positions.items(): + for n in tried_pos: + self.record_yellow(n, letter, fake_undo) + + # Excluded letters discovered so far. + self.letters_excluded: Set[Letter] = set() + if letters_excluded is not None: + for letter in letters_excluded: + self.record_gray(letter, fake_undo) + + def get_template(self) -> str: + """Return a representation of the board, e.g. __a_e""" + + template = '_' * self.solution_length + for n in self.letters_at_known_positions: + letter = self.letters_at_known_positions[n] + template = template[0:n] + letter + template[n + 1 :] + return template + + def get_alphabet(self) -> str: + """Return a colorized set of letters eliminated and still viable.""" + + letters_remaining = set(string.ascii_lowercase) + green_letters = set() + yellow_letters = set() + for letter in self.letters_excluded: + letters_remaining.remove(letter) + for letter in self.letters_at_known_positions.values(): + assert letter in letters_remaining + green_letters.add(letter) + for letter in self.letters_at_unknown_positions.keys(): + if len(self.letters_at_unknown_positions[letter]) > 0: + assert letter in letters_remaining + yellow_letters.add(letter) + ret = '' + for letter in string.ascii_lowercase: + if letter in letters_remaining: + if letter in green_letters: + ret += ansi.bg('forest green') + ret += ansi.fg('black') + ret += letter + ret += ansi.reset() + elif letter in yellow_letters: + ret += ansi.bg('energy yellow') + ret += ansi.fg('black') + ret += letter + ret += ansi.reset() + else: + ret += letter + else: + ret += ansi.fg('black olive') + ret += letter + ret += ansi.reset() + # ret += ' ' + return ret + + def __repr__(self) -> str: + return self.get_alphabet() + + def adjust_existing_letters_in_solution_maxes( + self, max_max: int, undo: WordStateUndo + ) -> None: + """We've determined, based on info about letters we know to be in the + solution and their min..max counts, what the maximum max of + any letter should be. Check all letters we know to be in the + solution and maybe tighten their maxes. If we do, remember it + for later undo purposes. + + """ + for letter in self.letters_in_solution.keys(): + old_max = self.letters_in_solution[letter][1] + new_max = min(max_max, old_max) + if old_max != new_max: + self.letters_in_solution[letter][1] = new_max + undo.mods.append( + { + "type": WordStateUndoType.LETTER_IN_SOLUTION_MAX_CHANGE, + "letter": letter, + "old_max": old_max, + } + ) + + def record_letter_in_solution( + self, + letter: Letter, + undo: WordStateUndo, + exact_count: Optional[int] = None, + ) -> None: + """Letter is a (maybe new, may existing in a special case, see below) + letter that we know is in the solution. For each letter we + know is in the solution, we track a min..max window indicating + how many times that letter is permitted to occur in the + solution. Manage those here. + + """ + + # If letter is already here, allow it to change bounds if it + # came with an exact_count. + if letter in self.letters_in_solution: + if exact_count is not None: + old_min = self.letters_in_solution[letter][0] + new_min = exact_count + if old_min != new_min: + self.letters_in_solution[letter][0] = new_min + undo.mods.append( + { + "type": WordStateUndoType.LETTER_IN_SOLUTION_MIN_CHANGE, + "letter": letter, + "old_min": old_min, + } + ) + old_max = self.letters_in_solution[letter][1] + new_max = exact_count + if old_max != new_max: + self.letters_in_solution[letter][1] = new_max + undo.mods.append( + { + "type": WordStateUndoType.LETTER_IN_SOLUTION_MAX_CHANGE, + "letter": letter, + "old_max": old_max, + } + ) + + # Also... since we now know exactly how many of this + # letter there are, maybe tighten the rest's maxes. + if exact_count != 1: + num_letters_known = len(self.letters_in_solution) - 1 + exact_count + max_max = self.solution_length - (num_letters_known - 1) + self.adjust_existing_letters_in_solution_maxes(max_max, undo) + return + + # If we're here, letter is a newly discovered letter in the + # solution. Such a letter will likely affect the max count of + # existing letters since, as new letters are discovered, there + # is less room for the other ones in the solution. + if exact_count is None: + num_letters_known = len(self.letters_in_solution) + 1 + else: + num_letters_known = len(self.letters_in_solution) + exact_count + max_max = self.solution_length - (num_letters_known - 1) + self.adjust_existing_letters_in_solution_maxes(max_max, undo) + + # Finally, add the new letter's record with its initial min/max. + if exact_count is None: + initial_max = min( + max_max, + self.max_letter_population_per_word[letter], + ) + initial_min = 1 + else: + initial_max = exact_count + initial_min = exact_count + self.letters_in_solution[letter] = [initial_min, initial_max] + undo.mods.append( + { + "type": WordStateUndoType.LETTER_IN_SOLUTION_ADDED_WITH_MIN_MAX, + "min": initial_min, + "max": initial_max, + "letter": letter, + } + ) + + def record_yellow( + self, + n: Position, + letter: Letter, + undo: WordStateUndo, + num_correct_doppelgangers: Optional[int] = None, + ) -> None: + """We've discovered a new yellow letter or a new place where an + existing yellow letter is still yellow. If + num_correct_doppelgangers is non-None, it means this letter is + wrong (gray) in the current location but right (green or + yellow) in other locations and we now know the precise count + of this letter in the solution -- tell the + record_letter_in_solution method. + + """ + if n not in self.letters_at_unknown_positions[letter]: + if ( + len(self.letters_at_unknown_positions[letter]) == 0 + or num_correct_doppelgangers is not None + ): + self.record_letter_in_solution(letter, undo, num_correct_doppelgangers) + self.letters_at_unknown_positions[letter].add(n) + undo.mods.append( + { + "type": WordStateUndoType.YELLOW_LETTER_ADDED, + "letter": letter, + "position": n, + } + ) + + def record_green(self, n: Position, letter: Letter, undo: WordStateUndo): + """We found a new green letter.""" + + if n not in self.letters_at_known_positions: + self.letters_at_known_positions[n] = letter + undo.mods.append( + { + "type": WordStateUndoType.GREEN_LETTER_ADDED, + "letter": letter, + "position": n, + } + ) + self.record_letter_in_solution(letter, undo) + + def record_gray(self, letter: Letter, undo: WordStateUndo) -> None: + """We found a new gray letter.""" + + if letter not in self.letters_excluded: + self.letters_excluded.add(letter) + undo.mods.append( + { + "type": WordStateUndoType.GRAY_LETTER_ADDED, + "letter": letter, + } + ) + + def record_guess_and_hint(self, guess: Word, hints: Dict[Position, Hint]): + """Make a guess and change state based on the hint. Remember how to + undo everything later. + + """ + undo = WordStateUndo(guess=guess, hints=hints, mods=[]) + for n, letter in enumerate(guess): + hint = hints[n] + + if hint is Hint.GRAY_WRONG: + # Exclude letters we got WRONG _unless_ we guessed the + # same letter elsewhere and got a yellow/green there. + # In this case the WRONG hint is not saying this + # letter isn't in the word (it is) but rather that + # there aren't N+1 instances of this letter. In this + # edge case we _do_ know that the letter is not valid + # in this position, though; treat it as yellow. + num_correct_doppelgangers = 0 + for k, other in enumerate(guess): + if other == letter and n != k and hints[k] != Hint.GRAY_WRONG: + num_correct_doppelgangers += 1 + if num_correct_doppelgangers == 0: + self.record_gray(letter, undo) + else: + # Treat this as a yellow; we know letter can't go + # here or it would have been yellow/green. + self.record_yellow(n, letter, undo, num_correct_doppelgangers) + elif hint is Hint.YELLOW_LETTER_RIGHT_POSITION_WRONG: + self.record_yellow(n, letter, undo) + elif hint is Hint.GREEN_LETTER_IN_RIGHT_POSITION: + self.record_green(n, letter, undo) + self.undo_info.append(undo) + + def undo_guess(self) -> None: + """Unmake a guess and revert back to a previous state.""" + + assert len(self.undo_info) > 0 + undo = self.undo_info[-1] + self.undo_info = self.undo_info[:-1] + + # We iterate the mods in reverse order so we never have weird + # apply/undo ordering artifacts. + for mod in reversed(undo.mods): + mod_type = mod['type'] + letter = mod['letter'] + if mod_type is WordStateUndoType.GRAY_LETTER_ADDED: + self.letters_excluded.remove(letter) + elif mod_type is WordStateUndoType.YELLOW_LETTER_ADDED: + pos = mod['position'] + self.letters_at_unknown_positions[letter].remove(pos) + elif mod_type is WordStateUndoType.GREEN_LETTER_ADDED: + pos = mod['position'] + del self.letters_at_known_positions[pos] + elif mod_type is WordStateUndoType.LETTER_IN_SOLUTION_MIN_CHANGE: + old_min = mod['old_min'] + self.letters_in_solution[letter][0] = old_min + elif mod_type is WordStateUndoType.LETTER_IN_SOLUTION_MAX_CHANGE: + old_max = mod['old_max'] + self.letters_in_solution[letter][1] = old_max + elif mod_type is WordStateUndoType.LETTER_IN_SOLUTION_ADDED_WITH_MIN_MAX: + del self.letters_in_solution[letter] + + +class AutoplayOracle(object): + """The class that knows the right solution and can give hints in + response to guesses. + + """ + + def __init__(self, solution: Word): + super().__init__() + self.solution = solution.lower() + self.solution_letter_count = Counter(self.solution) + self.solution_letter_to_pos = defaultdict(set) + for n, letter in enumerate(self.solution): + self.solution_letter_to_pos[letter].add(n) + self.hint_quota_by_letter = Counter(self.solution) + + def judge_guess(self, guess: Word) -> Dict[Position, Hint]: + """Returns a mapping from position -> Hint to indicate + whether each letter in the guess string is green, yellow + or gray. + + """ + assert len(guess) == len(self.solution) + hint_by_pos: Dict[Position, Hint] = {} + letter_to_pos = defaultdict(set) + hint_quota_by_letter = self.hint_quota_by_letter.copy() + + for position, letter in enumerate(guess): + letter_to_pos[letter].add(position) + + if letter == self.solution[position]: # green + if hint_quota_by_letter[letter] == 0: + # We must tell them this letter is green in this + # position but we've exhausted our quota of hints + # for this letter. There must exist some yellow + # hint we previously gave that we need to turn to + # gray (wrong). + for other in letter_to_pos[letter]: + if other != position: + if ( + hint_by_pos[other] + == Hint.YELLOW_LETTER_RIGHT_POSITION_WRONG + ): + hint_by_pos[other] = Hint.GRAY_WRONG + break + hint_by_pos[position] = Hint.GREEN_LETTER_IN_RIGHT_POSITION + + elif self.solution_letter_count[letter] > 0: # yellow + if hint_quota_by_letter[letter] == 0: + # We're out of hints for this letter. All the + # other hints must be green or yellow. Tell them + # this one is gray (wrong). + hint_by_pos[position] = Hint.GRAY_WRONG + else: + hint_by_pos[position] = Hint.YELLOW_LETTER_RIGHT_POSITION_WRONG + + else: # gray + hint_by_pos[position] = Hint.GRAY_WRONG + if hint_quota_by_letter[letter] > 0: + hint_quota_by_letter[letter] -= 1 + return hint_by_pos + + +class AutoPlayer(object): + """This is the class that knows how to guess given the current game + state along with several support methods. + + """ + + def __init__(self): + super().__init__() + self.solution_length = None + + # Guess judge + self.oracle = None + + # Board state tracker and move undoer + self.word_state = None + + # The position hash has known best guesses for some subset of + # remaining words. See --mode=PRECOMPUTE for how to populate. + self.position_hash = {} + filename = config.config['hash_file'] + if filename is not None and file_utils.file_is_readable(filename): + logger.debug(f'Initializing position hash from {filename}...') + with open(filename, 'r') as rf: + for line in rf: + line = line[:-1] + line = line.strip() + line = re.sub(r'#.*$', '', line) + if len(line) == 0: + continue + (key, word) = line.split(':') + (count, fprint) = key.split('@') + count = count.strip() + count = int(count) + fprint = fprint.strip() + word = word.strip() + self.position_hash[(count, fprint)] = word + logger.debug(f'...hash contains {len(self.position_hash)} entries.') + + # All legal solutions pre-sorted by length. + self.all_possible_solutions_by_length = defaultdict(list) + filename = config.config['solutions_file'] + if filename is not None and file_utils.file_is_readable(filename): + logger.debug(f'Initializing valid solution word list from {filename}...') + with open(filename) as rf: + for word in rf: + word = word[:-1] + word = word.lower() + self.all_possible_solutions_by_length[len(word)].append(word) + else: + logger.error('A valid --solutions_file is required.') + sys.exit(0) + + # All legal guesses pre-sorted by length. + self.all_possible_guesses_by_length = defaultdict(list) + filename = config.config['guesses_file'] + if filename is not None and file_utils.file_is_readable(filename): + logger.debug(f'Initializing legal guess word list from {filename}...') + with open(filename) as rf: + for word in rf: + word = word[:-1] + word = word.lower() + self.all_possible_guesses_by_length[len(word)].append(word) + else: + logger.error('A valid --guesses_file is required.') + sys.exit(0) + + def new_word( + self, + length: int, + oracle: Optional[AutoplayOracle], + word_state: Optional[WordState], + ) -> None: + """Here's a new word to guess. Reset state to play a new game. On + principle we don't give this class the solution. Instead, we + just give it length to indicate the number of characters in + the solution. Guesses will be turned into hints by the + oracle. The current game state is tracked by the + word_state. + + """ + self.solution_length = length + self.oracle = oracle + self.word_state = word_state + + def get_all_possible_solutions(self) -> List[Word]: + """Given the current known word state, compute the subset of all + possible solutions that are still possible. Note: this method + guarantees to return the possible solutions list in sorted + order. + + """ + + def is_possible_solution(solution: Word, word_state: WordState) -> bool: + """Note: very perf sensitive code; inner loop.""" + + letters_seen: Dict[Letter, int] = defaultdict(int) + for n, letter in enumerate(solution): + # The word can't contain letters we know aren't in the + # solution. + if letter in word_state.letters_excluded: + return False + + # If we already tried this letter in this position and + # it wasn't green, this isn't a possible solution. + if n in word_state.letters_at_unknown_positions[letter]: + return False + + # If we know a letter is in a position, solution words + # must have that letter in that position. + if ( + n in word_state.letters_at_known_positions + and letter != word_state.letters_at_known_positions[n] + ): + return False + letters_seen[letter] += 1 + + # Finally, the word must include all letters presently + # known to be in the solution to be viable. + for letter, min_max in word_state.letters_in_solution.items(): + num_seen = letters_seen[letter] + if num_seen < min_max[0]: + return False + elif num_seen > min_max[1]: + return False + return True + + possible_solutions = [] + for word in self.all_possible_solutions_by_length[self.solution_length]: + if is_possible_solution(word, self.word_state): + possible_solutions.append(word) + + # Note: because self.all_possible_solutions_by_length is sorted + # and we iterated it in order, possible_solutions is also sorted + # already. + # assert possible_solutions == sorted(possible_solutions) + return possible_solutions + + def get_frequency_and_frequency_by_position_tables( + self, + possible_solutions: List[Word], + ) -> Tuple[Dict[Letter, float], List[Dict[Letter, float]]]: + """This method is used by heuristic mode. It returns two tables: + + 1. The frequency count by letter for words in possible_solutions + to encourage guesses composed of common letters. + 2. A letter-in-position bonus term to encourage guesses with + letters in positions that occur frequently in the solutions. + + """ + template = self.word_state.get_template() + pfreq: List[Dict[Letter, float]] = [] + pop_letters: List[Dict[Letter, int]] = [] + for n in range(len(template)): + pop_letters.append(defaultdict(int)) + pfreq.append({}) + + freq: Dict[Letter, float] = {} + for word in possible_solutions: + letter_filter = set() + for n, letter in enumerate(word): + + # Only count frequency of letters still to be filled in. + if template[n] != '_': + continue + + # Do not give a full frequency bonus to repeated letters. + if letter not in letter_filter: + freq[letter] = freq.get(letter, 0) + 1 + letter_filter.add(letter) + else: + freq[letter] += 0.1 + pop_letters[n][letter] += 1 # type: ignore + + # Reward guesses that place the most popular letter in a position. + # Save the top 3 letters per position. + # don't give a bonus if letters spread all over the place? + # only give a bonus to a given letter in one position? + total_letters_in_position = len(possible_solutions) + for n in range(len(template)): + for letter, count in sorted(pop_letters[n].items(), key=lambda x: -x[1]): + if count <= 1: + break + normalized = count / total_letters_in_position + assert 0.0 < normalized <= 1.0 + if normalized > 0.08: + pfreq[n][letter] = normalized + else: + break + return (freq, pfreq) + + def dump_frequency_data( + self, + possible_solutions: List[Word], + letter_frequency: Dict[Letter, float], + letter_position_frequency: List[Dict[Letter, float]], + ) -> None: + """Just logs the frequency tables we computed above.""" + + logger.debug('Unknown letter(s) frequency table: ') + out = '' + for letter, weight in sorted(letter_frequency.items(), key=lambda x: -x[1]): + out += f'{letter}:{weight}, ' + if len(out): + out = out[:-2] + logger.debug(out) + + logger.debug('Unknown letter-in-position bonus table: ') + out = '' + for n in range(len(possible_solutions[0])): + pop = letter_position_frequency[n] + for letter, weight in sorted(pop.items(), key=lambda x: -x[1]): + out += f'pos{n}:{letter}@{weight:.5f}, ' + if len(out): + out = out[:-2] + logger.debug(out) + + def position_in_hash(self, num_potential_solutions: int, fprint: Fprint): + """Is a position in our hash table?""" + return (num_potential_solutions, fprint) in self.position_hash + + def guess_word(self) -> Optional[Word]: + """Compute a guess word and return it. Returns None on error.""" + + template = self.word_state.get_template() + possible_solutions = self.get_all_possible_solutions() + num_possible_solutions = len(possible_solutions) + fprint = hashlib.md5(possible_solutions.__repr__().encode('ascii')).hexdigest() + + n = num_possible_solutions + logger.debug( + string_utils.make_contractions( + f'There {string_utils.is_are(n)} {n} word{string_utils.pluralize(n)} ' + + f'({template} @ {fprint}).' + ) + ) + if num_possible_solutions < 30: + logger.debug( + string_utils.make_contractions( + f'{string_utils.capitalize_first_letter(string_utils.it_they(n))} ' + + f'{string_utils.is_are(n)}: {possible_solutions}' + ) + ) + logger.debug( + f'Letter count restrictions: {self.word_state.letters_in_solution}' + ) + if num_possible_solutions == 0: + logger.error('No possible solutions?!') + print('No possible solutions?!', file=sys.stderr) + print(self.word_state) + print(self.word_state.letters_in_solution) + return None + + elif num_possible_solutions == 1: + return possible_solutions[0] + + # Check the hash table for a precomputed best guess. + elif self.position_in_hash(num_possible_solutions, fprint): + guess = self.position_hash[(num_possible_solutions, fprint)] + logger.debug(f'hash hit: {guess}') + return guess + + # If there are just a few solutions possible, brute force the + # guess. This is expensive: for every possible solution it + # computes the entropy of every possible guess. Not fast for + # large numbers of solutions. + elif num_possible_solutions < 20: + logger.debug( + f'Only {num_possible_solutions} solutions; using brute force strategy.' + ) + return self.brute_force_internal( + possible_solutions, + self.all_possible_guesses_by_length[len(possible_solutions[0])], + 'brute_force', + ) + + # A hybrid approach: narrow down the guess list using + # heuristic scoring and then compute the entropy of the topN + # guesses via brute force. + elif num_possible_solutions < 100: + logger.debug( + f'Only {num_possible_solutions} solutions; using hybrid strategy.' + ) + return self.hybrid_search(possible_solutions) + + # There are a lot of words left; score the guesses based on + # fast heuristics (i.e. letter frequency). + else: + logger.debug( + f'There are {num_possible_solutions} solutions; using fast heuristics.' + ) + return self.heuristics_search(possible_solutions) + + def brute_force_internal( + self, + possible_solutions: List[Word], + all_guesses: List[Word], + label: str, + ) -> Optional[Word]: + """Assume every possible solution is the answer, in turn. For each + one, try all_guesses and pay attention to the hint we would + get back. Compute the entropy of each guess and return the + guess with the highest entropy -- i.e. the guess that gives us + the most information on average; or, the guess whose results + would take the most bits to represent. + + Note, this is expensive. O(num_possible_solutions * all_guesses) + + """ + num_possible_solutions = len(possible_solutions) + if num_possible_solutions == 1: + return possible_solutions[0] + possible_solutions_set = set(possible_solutions) # for O(1) lookups + + # Buckets count distinct outcomes of a guess. e.g. if a guess + # yields the hint G_Y__ that outcome is assigned a bucket + # number and we will increment the count of how many times + # that outcome happened for this guess across all possible + # solutions. + bucket_population_by_guess: Dict[Word, Dict[Bucket, int]] = {} + for guess in all_guesses: + bucket_population_by_guess[guess] = defaultdict(int) + + # Pretend that each possible solution is the real solution + # and make every possible guess for each. + for solution in possible_solutions: + oracle = AutoplayOracle(solution) + for guess in all_guesses: + hints = oracle.judge_guess(guess) + + # Note: this is a really good way to make sure that + # make/unmake moves works: + # + # before = self.word_state.__repr__() + self.word_state.record_guess_and_hint(guess, hints) + # during = self.word_state.__repr__() + + # Map the hint returned into a bucket number and + # keep track of population per bucket. Below: + # + # n is a position := {0, 1, 2, 3, 4} + # hint[n] := {1, 2, 3} + # + bucket: Bucket = 0 + for n in range(len(guess)): + bucket += hints[n] * (3**n) + bucket_population_by_guess[guess][bucket] += 1 + self.word_state.undo_guess() + + # after = self.word_state.__repr__() + # if before != after: + # print(f'BEFORE: {before}') + # print(f' WORD: {colorize_guess(guess, hints)}') + # print(f' HINT: {hints}') + # print(f'DURING: {during}') + # print(f' AFTER: {after}') + # assert False + + # Compute the entropy of every guess across all possible + # solutions: + # + # https://markmliu.medium.com/what-in-the-wordle-5dc5ed94fe2 + # https://machinelearningmastery.com/what-is-information-entropy/ + # https://en.wikipedia.org/wiki/Entropy_(information_theory) + best_entropy = None + best_guess = None + entropy: Dict[Word, float] = {} + for guess in all_guesses: + entropy[guess] = 0.0 + for bucket in bucket_population_by_guess[guess]: + + # We counted how many times this outcome occurred. + # The probabilty of this outcome = count / total. + p = float(bucket_population_by_guess[guess][bucket]) + p /= num_possible_solutions + entropy[guess] += p * math.log2(p) + entropy[guess] = -entropy[guess] + + if best_entropy is None: + best_entropy = entropy[guess] + best_guess = guess + else: + + # We always choose the guess with the highest entropy + # because this guess gives us the most information in + # the average case, i.e. it takes the most bits to + # represent the average outcome of this guess. + # + # However, in practice, usually several guesses tie + # for best. Prefer guesses that are also potential + # solutions (not just legal guesses) + if entropy[guess] > best_entropy or ( + entropy[guess] == best_entropy and guess in possible_solutions_set + ): + best_entropy = entropy[guess] + best_guess = guess + + # This is just logging the results. Display the guesses with + # the highest entropy but also display the entropy of every + # possible solution, too, even if they are not best. + possible_solutions_seen = 0 + best_entropy = None + best_count = 0 + for n, (guess, guess_entropy) in enumerate( + sorted(entropy.items(), key=lambda x: -x[1]) + ): + if best_entropy is None: + best_entropy = guess_entropy + if guess in possible_solutions_set: + possible_solutions_seen += 1 + logger.debug( + f'{label}: #{n}: {guess} with {guess_entropy:.5f} bits <--' + ) + elif guess_entropy == best_entropy and best_count < 15: + logger.debug(f'{label}: #{n}: {guess} with {guess_entropy:.5f} bits') + best_count += 1 + logger.debug(f'{label}: best guess is {best_guess}.') + return best_guess + + def hybrid_search(self, possible_solutions: List[Word]) -> Optional[Word]: + """Use heuristic scoring to reduce the number of guesses before + calling brute force search. + + """ + (freq, pfreq) = self.get_frequency_and_frequency_by_position_tables( + possible_solutions + ) + self.dump_frequency_data(possible_solutions, freq, pfreq) + scored_guesses = self.assign_scores(possible_solutions, freq, pfreq) + best_guess = None + + topn_guesses = [] + count = 1 + for guess, score in sorted(scored_guesses.items(), key=lambda x: -x[1]): + logger.debug(f'hybrid: heuristic #{count} = {guess} with {score:.5f}') + topn_guesses.append(guess) + count += 1 + if count > 10: + break + + best_guess = self.brute_force_internal( + possible_solutions, topn_guesses, 'hybrid: brute_force' + ) + return best_guess + + def assign_scores( + self, + possible_solutions: List[Word], + freq: Dict[Letter, float], + pfreq: List[Dict[Letter, float]], + ) -> Dict[Word, float]: + """Given some letter frequency and letter+position bonus data, assign + a score to every possible guess. + + """ + num_possible_solutions = len(possible_solutions) + assert num_possible_solutions > 1 + template = self.word_state.get_template() + + # Give every word a score composed of letter frequencies and letter + # in position frequencies. This score attempts to approximate the + # result of brute_force_search less expensively. + word_scores: Dict[Word, float] = {} + for guess in possible_solutions: + freq_term = 0.0 + pfreq_term = 0.0 + + letter_filter = set() + for n, letter in enumerate(guess): + + # Ignore letters we already know. + if template[n] != '_': + continue + + # Is there a bonus for this letter in this position? (pfreq) + pop = pfreq[n] + if letter in pop: + pfreq_term += pop[letter] * num_possible_solutions / 4 + + # Don't count freq bonus more than once per letter. (freq) + if letter in letter_filter: + continue + freq_term += freq.get(letter, 0.0) + letter_filter.add(letter) + score = freq_term + pfreq_term + word_scores[guess] = score + return word_scores + + def heuristics_search(self, possible_solutions: List[Word]) -> Word: + """The dumbest but fastest search. Use fast heuristics to score each + possible guess and then guess the one with the highest + score. + + """ + (freq, pfreq) = self.get_frequency_and_frequency_by_position_tables( + possible_solutions + ) + self.dump_frequency_data(possible_solutions, freq, pfreq) + scored_guesses = self.assign_scores(possible_solutions, freq, pfreq) + best_guess = None + for n, (guess, score) in enumerate( + sorted(scored_guesses.items(), key=lambda x: -x[1]) + ): + if best_guess is None: + best_guess = guess + if n < 20: + logger.debug(f'heuristic: #{n}: {guess} with {score:.5f}') + assert best_guess is not None + return best_guess + + +def colorize_guess(guess: Word, hints: Dict[Position, Hint]) -> str: + """Use hints to make the letters green/yellow/gray.""" + ret = '' + for n, letter in enumerate(guess): + hint = hints[n] + if hint is Hint.GRAY_WRONG: + ret += ansi.bg('mist gray') + elif hint is Hint.YELLOW_LETTER_RIGHT_POSITION_WRONG: + ret += ansi.bg('energy yellow') + elif hint is Hint.GREEN_LETTER_IN_RIGHT_POSITION: + ret += ansi.bg('forest green') + ret += ansi.fg('black') + ret += letter + ret += ansi.reset() + return ret + + +def get_max_letter_population() -> Dict[Letter, int]: + filename = config.config['solutions_file'] + max_letter_population_per_word: Dict[Letter, int] = defaultdict(int) + if filename is not None and file_utils.file_is_readable(filename): + logger.debug( + 'Figuring out all letters\' max frequency in the solution space...' + ) + with open(filename) as rf: + for word in rf: + word = word[:-1] + word = word.lower() + letter_pop = Counter(word) + for letter, pop in letter_pop.items(): + if pop > max_letter_population_per_word[letter]: + max_letter_population_per_word[letter] = pop + else: + logger.error('A valid --solutions_file is required.') + sys.exit(0) + return max_letter_population_per_word + + +def autoplay( + solution: Word, + oracle: AutoplayOracle, + word_state: WordState, + player: AutoPlayer, + quiet: bool = False, +): + """Make guesses one by one until arriving at a known solution.""" + if not quiet: + logger.debug('Autoplayer mode...') + player.new_word(len(solution), oracle, word_state) + + guesses = [] + while True: + guess = player.guess_word() + if guess is not None: + hints = oracle.judge_guess(guess) + word_state.record_guess_and_hint(guess, hints) + guesses.append(guess) + if not quiet: + colorized_guess = colorize_guess(guess, hints) + print(f'Guess #{len(guesses)}: {colorized_guess} => {word_state}') + if guess == solution: + break + if guess is None: + logger.error(f'"{solution}" is not in my --solutions_file.') + break + return guesses + + +def cheat(): + """Cheater! Given a board state, determine the best guess. Note that + in this mode the solution is not known. + + """ + logger.debug('Cheater mode...') + + template = config.config['template'] + assert template + + # Extract known letter positions from the template. + template = template.lower() + letters_at_known_positions = {} + for n, letter in enumerate(template): + if letter != '_': + letters_at_known_positions[n] = letter + + # Initialize set of letters to be avoided. + avoid = config.config['letters_to_avoid'] + if not avoid: + avoid = '' + avoid = avoid.lower() + letters_to_avoid = set([letter for letter in avoid]) + + # Initialize the set of letters we know are in the solution but + # not where, yet. + in_word = config.config['letters_in_word'] + if not in_word: + in_word = '' + in_word = in_word.lower() + + # This is parsing out the --letters_in_word argument. The + # format is: + # + # <1 or more zero-based positions we already tried it> + # + # So, if we know an E is in the word (i.e. it's yellow) and + # we tried it in the first and third letter already: + # + # e02 + # + # Note: 0 means "the first letter", i.e. position is zero based. + # + # You can stack letters this way. e.g.: + # + # e02a3 + letters_in_word_at_unknown_position = defaultdict(set) + last_letter = None + for letter in in_word: + if letter.isdigit(): + assert last_letter + letters_in_word_at_unknown_position[last_letter].add(int(letter)) + elif letter.isalpha(): + last_letter = letter + + max_letter_pop_per_word = get_max_letter_population() + word_state = WordState( + len(template), + max_letter_pop_per_word, + letters_at_known_positions=letters_at_known_positions, + letters_at_unknown_positions=letters_in_word_at_unknown_position, + letters_excluded=letters_to_avoid, + ) + + player = AutoPlayer() + player.new_word(len(template), None, word_state) + return player.guess_word() + + +def selftest(): + """Autoplay every possible solution and pay attention to statistics.""" + + logger.debug('Selftest mode...') + total_guesses = 0 + total_words = 0 + max_guesses = None + max_guesses_words = [] + every_guess = set() + hist = histogram.SimpleHistogram( + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 100)] + ) + top_guess_number = defaultdict(dict) + num_losses = 0 + + player = AutoPlayer() + with open(config.config['solutions_file'], 'r') as rf: + contents = rf.readlines() + + max_letter_pop_per_word = get_max_letter_population() + start = time.time() + for word in contents: + word = word[:-1] + word = word.lower() + if len(word) != 5: + logger.warning( + f'Found word "{word}" in solutions file that is not 5 letters in length. Skipping it.' + ) + continue + oracle = AutoplayOracle(word) + word_state = WordState(len(word), max_letter_pop_per_word) + player.new_word(len(word), oracle, word_state) + + total_words += 1 + runtime = time.time() - start + print( + f'{total_words} / {len(contents)} ("{word}") = {total_words/len(contents)*100.0:.2f}% | {total_guesses/total_words:.3f} guesses/word | {runtime:.1f}s @ {runtime/total_words:.3f}s/word\r', + end='', + ) + if total_words % 100 == 0: + print(f'\nAfter {total_words} words:') + print( + f'...I made {total_guesses} guesses; ({total_guesses/total_words:.3f}/word)' + ) + print( + f'...Max guesses was {max_guesses} for {max_guesses_words}; I lost {num_losses} times.' + ) + print(f'...I made {len(every_guess)} total distinct "interior" guesses.') + print() + + guesses = autoplay(word, oracle, word_state, player, True) + guess_count = len(guesses) + if guess_count > 6: + num_losses += 1 + hist.add_item(guess_count) + total_guesses += guess_count + for n, guess in enumerate(guesses): + tops = top_guess_number[n] + tops[guess] = tops.get(guess, 0) + 1 + if n != len(guesses) - 1: + every_guess.add(guess) + if max_guesses is None or guess_count > max_guesses: + max_guesses = guess_count + max_guesses_words = [word] + elif guess_count == max_guesses: + max_guesses_words.append(word) + print("\nFinal Report:") + print("-------------") + print(f'On {total_words} words:') + print( + f'...I made {total_guesses} guesses; ({total_guesses / total_words:.3f} / word)' + ) + print( + f'...Max guesses was {max_guesses} for {max_guesses_words}; I lost {num_losses} times.' + ) + print(f'...I made {len(every_guess)} total distinct "interior" guesses.') + print() + for n in range(0, 8): + top_guesses = top_guess_number[n] + num = 0 + out = '' + print(f'Top guesses #{n+1}: ', end='') + for guess, count in sorted(top_guesses.items(), key=lambda x: -x[1]): + out += f'{guess}@{count}, ' + num += 1 + if num > 8: + break + out = out[:-2] + print(out) + print() + print(hist) + + +@par.parallelize(method=par.Method.PROCESS) +def do_words( + solutions: List[Word], + shard_num: int, + shared_cache_name: str, + lock: multiprocessing.RLock, + max_letter_pop_per_word: Dict[Letter, int], +): + """Work on precomputing one shard of the solution space, in parallel.""" + + logger.debug(f'Shard {shard_num} owns solutions {solutions[0]}..{solutions[-1]}.') + player = AutoPlayer() + length = len(solutions[0]) + shared_cache = SharedDict(shared_cache_name, 0, lock) + begin = solutions[0] + end = solutions[-1] + + passes = 0 + while True: + num_computed = 0 + passes += 1 + assert passes < 10 + local_cache: Dict[Tuple[int, Fprint], Word] = {} + + for n, solution in enumerate(solutions): + oracle = AutoplayOracle(solution) + word_state = WordState(length, max_letter_pop_per_word) + player.new_word(length, oracle, word_state) + guesses = [] + + # Make guesses until the next guess is not in the hash or + # the shared dict. + while True: + remaining_words = player.get_all_possible_solutions() + num_remaining_words = len(remaining_words) + if num_remaining_words <= 1: + break + + sig_remaining_words = hashlib.md5( + remaining_words.__repr__().encode('ascii') + ).hexdigest() + key = (num_remaining_words, sig_remaining_words) + + if player.position_in_hash(num_remaining_words, sig_remaining_words): + provenance = 'game_hash' + guess = player.guess_word() + elif key in local_cache: + provenance = 'local_cache' + guess = local_cache[key] + elif key in shared_cache: + provenance = 'shared_cache' + guess = shared_cache[key] + else: + provenance = 'computed' + guess = player.brute_force_internal( + remaining_words, + player.all_possible_guesses_by_length[length], + 'precompute', + ) + local_cache[key] = guess + shared_cache[key] = guess + num_computed += 1 + assert guess + guesses.append(guess) + hints = oracle.judge_guess(guess) + word_state.record_guess_and_hint(guess, hints) + print( + f'shard{shard_num}: ' + + f'{passes}/{n}/{len(solutions)}/{solution}> ' + + f'{num_remaining_words} @ {sig_remaining_words}: {guesses} # {provenance}' + ) + + # When we can make it through a pass over all solutions and + # never miss the hash or shared dict, we're done. + if num_computed == 0: + print( + f'{ansi.bg("green")}{ansi.fg("black")}' + + f'shard{shard_num}: "{begin}".."{end}" is finished!' + + f'{ansi.reset()}' + ) + break + shared_cache.close() + return f'(shard {shard_num} done)' + + +def precompute(): + """Precompute the best guess in every situation via the expensive + brute force / entropy method. Break the solutions list into + shards and execute each one in parallel. Persist the concatenated + results in a file. + + """ + with open(config.config['solutions_file'], 'r') as rf: + contents = rf.readlines() + all_words = [] + length = None + for word in contents: + word = word[:-1] + word = word.lower() + if length is None: + length = len(word) + else: + assert len(word) == length + all_words.append(word) + + max_letter_pop_per_word = get_max_letter_population() + shards = [] + logger.debug('Sharding words into groups of 10.') + for subset in list_utils.shard(all_words, 10): + shards.append([x for x in subset]) + + logger.debug('Kicking off helper pool.') + + # Shared cache is a dict that is slow to read/write but is visible + # to all shards so that they can benefit from results already + # computed in one of the other workers. 10 pages (~40kb) of + # memory. + shared_cache = SharedDict("wordle_shared_dict", 4096 * 10) + results = [] + try: + for n, shard in enumerate(shards): + results.append( + do_words( + shard, + n, + shared_cache.get_name(), + SharedDict.LOCK, + max_letter_pop_per_word, + ) + ) + smart_future.wait_all(results) + + with open(config.config['hash_file'], 'a') as wf: + for key, value in shared_cache.items(): + print(f'{key[0]} @ {key[1]}: {value}', file=wf) + finally: + shared_cache.close() + shared_cache.cleanup() + executors.DefaultExecutors().process_pool().shutdown() + + +def get_legal_guesses() -> Set[Word]: + legal_guesses = set() + with open(config.config['guesses_file'], 'r') as rf: + contents = rf.readlines() + for line in contents: + line = line[:-1] + line = line.lower() + legal_guesses.add(line) + return legal_guesses + + +def get_solution() -> Word: + if config.config['template'] is not None: + solution = config.config['template'] + print(ansi.clear()) + else: + with open(config.config['solutions_file'], 'r') as rf: + contents = rf.readlines() + solution = random.choice(contents) + solution = solution[:-1] + solution = solution.lower() + solution = solution.strip() + return solution + + +def give_hint(num_hints: int, player: AutoPlayer, word_state: WordState): + """Give a smart(?) hint to the guesser.""" + + possible_solutions = player.get_all_possible_solutions() + n = len(possible_solutions) + if num_hints == 1: + print( + f'There {string_utils.is_are(n)} {n} possible solution{string_utils.pluralize(n)}.' + ) + elif num_hints == 2: + (freq, _) = player.get_frequency_and_frequency_by_position_tables( + possible_solutions + ) + hint_letters = sorted(freq.items(), key=lambda x: -x[1]) + good_hints = set(string.ascii_lowercase) + for letter in word_state.letters_at_unknown_positions.keys(): + if len(word_state.letters_at_unknown_positions[letter]) > 0: + if letter in good_hints: + good_hints.remove(letter) + for letter in word_state.letters_at_known_positions.values(): + if letter in good_hints: + good_hints.remove(letter) + limit = 2 + if n < 10: + limit = 1 + for letter, _ in hint_letters: + if letter in good_hints: + print( + f'"{letter}" is popular in the possible solution{string_utils.pluralize(n)}.' + ) + limit -= 1 + if limit == 0: + break + elif num_hints == 3: + limit = 3 + if n < 10: + limit = 1 + for possibility in random.sample(possible_solutions, min(limit, n)): + print(f'Maybe something like "{possibility}"?') + elif num_hints >= 4: + best_guess = player.guess_word() + print(f'Try "{best_guess}"') + + +def play() -> None: + """Allow users to play and color in the letter for them.""" + + legal_guesses = get_legal_guesses() + solution = get_solution() + oracle = AutoplayOracle(solution) + max_letter_pop_per_word = get_max_letter_population() + word_state = WordState(len(solution), max_letter_pop_per_word) + player = AutoPlayer() + player.new_word(len(solution), oracle, word_state) + + num_guesses = 0 + prompt = 'Guess #_/6 (or "?" for a hint): ' + padding = ' ' * len(prompt) + colorized_guess = "▢" * len(solution) + guess = None + num_hints = 0 + + while True: + # Print current state + template. + print(padding + colorized_guess + " " + word_state.__repr__()) + if guess == solution: + print('Nice!') + break + elif num_guesses >= 6: + print('Better luck next time.') + print(padding + f'{solution}') + break + + # Get a guess / command. + guess = input(prompt.replace('_', str(num_guesses + 1))).lower().strip() + + # Parse it. + if guess == '?': + num_hints += 1 + give_hint(num_hints, player, word_state) + continue + elif guess == '#brute': + remaining_words = player.get_all_possible_solutions() + brute = player.brute_force_internal( + remaining_words, + player.all_possible_guesses_by_length[len(solution)], + 'precompute', + ) + print(word_state) + print(brute) + continue + elif len(guess) != len(solution) or guess not in legal_guesses: + print(f'"{guess}" is not a legal guess, try again.') + continue + + # If we get here it was a guess. Process it. + num_guesses += 1 + hints = oracle.judge_guess(guess) + colorized_guess = colorize_guess(guess, hints) + word_state.record_guess_and_hint(guess, hints) + num_hints = 0 + + +# The bootstrap.initialize decorator takes care of parsing our commandline +# flags and populating config. It can also do cool things like time and +# profile the code run within it, audit imports, profile memory usage, +# and break into pdb on unhandled exception. +@bootstrap.initialize +def main() -> Optional[int]: + mode = config.config['mode'].upper().strip() + if mode == 'AUTOPLAY': + solution = config.config['template'] + assert solution + solution = solution.lower() + oracle = AutoplayOracle(solution) + max_letter_pop_per_word = get_max_letter_population() + word_state = WordState(len(solution), max_letter_pop_per_word) + player = AutoPlayer() + autoplay(solution, oracle, word_state, player) + return None + elif mode == 'CHEAT': + return cheat() + elif mode == 'PLAY': + play() + return None + elif mode == 'SELFTEST': + selftest() + return None + elif mode == 'PRECOMPUTE': + precompute() + return None + raise Exception('wtf?') + + +if __name__ == '__main__': + main() diff --git a/examples/wordle/wordle_guesses.txt b/examples/wordle/wordle_guesses.txt new file mode 100644 index 0000000..51637f5 --- /dev/null +++ b/examples/wordle/wordle_guesses.txt @@ -0,0 +1,12972 @@ +aahed +aalii +aargh +aarti +abaca +abaci +aback +abacs +abaft +abaka +abamp +aband +abase +abash +abask +abate +abaya +abbas +abbed +abbes +abbey +abbot +abcee +abeam +abear +abele +abers +abets +abhor +abide +abies +abled +abler +ables +ablet +ablow +abmho +abode +abohm +aboil +aboma +aboon +abord +abore +abort +about +above +abram +abray +abrim +abrin +abris +absey +absit +abuna +abune +abuse +abuts +abuzz +abyes +abysm +abyss +acais +acari +accas +accoy +acerb +acers +aceta +achar +ached +aches +achoo +acids +acidy +acing +acini +ackee +acker +acmes +acmic +acned +acnes +acock +acold +acorn +acred +acres +acrid +acros +acted +actin +acton +actor +acute +acyls +adage +adapt +adaws +adays +adbot +addax +added +adder +addio +addle +adeem +adept +adhan +adieu +adios +adits +adman +admen +admin +admit +admix +adobe +adobo +adopt +adore +adorn +adown +adoze +adrad +adred +adsum +aduki +adult +adunc +adust +advew +adyta +adzed +adzes +aecia +aedes +aegis +aeons +aerie +aeros +aesir +afald +afara +afars +afear +affix +afire +aflaj +afoot +afore +afoul +afrit +afros +after +again +agama +agami +agape +agars +agast +agate +agave +agaze +agene +agent +agers +agger +aggie +aggri +aggro +aggry +aghas +agila +agile +aging +agios +agism +agist +agita +aglee +aglet +agley +agloo +aglow +aglus +agmas +agoge +agone +agons +agony +agood +agora +agree +agria +agrin +agros +agued +agues +aguna +aguti +ahead +aheap +ahent +ahigh +ahind +ahing +ahint +ahold +ahull +ahuru +aidas +aided +aider +aides +aidoi +aidos +aiery +aigas +aight +ailed +aimed +aimer +ainee +ainga +aioli +aired +airer +airns +airth +airts +aisle +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 +alarm +alary +alate +alays +albas +albee +album +alcid +alcos +aldea +alder +aldol +aleck +alecs +alefs +aleft +aleph +alert +alews +aleye +alfas +algae +algal +algas +algid +algin +algor +algum +alias +alibi +alien +alifs +align +alike +aline +alist +alive +aliya +alkie +alkos +alkyd +alkyl +allay +allee +allel +alley +allis +allod +allot +allow +alloy +allyl +almah +almas +almeh +almes +almud +almug +alods +aloed +aloes +aloft +aloha +aloin +alone +along +aloof +aloos +aloud +alowe +alpha +altar +alter +altho +altos +alula +alums +alure +alvar +alway +amahs +amain +amass +amate +amaut +amaze +amban +amber +ambit +amble +ambos +ambry +ameba +ameer +amend +amene +amens +ament +amias +amice +amici +amide +amido +amids +amies +amiga +amigo +amine +amino +amins +amirs +amiss +amity +amlas +amman +ammon +ammos +amnia +amnic +amnio +amoks +amole +among +amort +amour +amove +amowt +amped +ample +amply +ampul +amrit +amuck +amuse +amyls +anana +anata +ancho +ancle +ancon +andro +anear +anele +anent +angas +angel +anger +angle +anglo +angry +angst +anigh +anile +anils +anima +anime +animi +anion +anise +anker +ankhs +ankle +ankus +anlas +annal +annas +annat +annex +annoy +annul +anoas +anode +anole +anomy +ansae +antae +antar +antas +anted +antes +antic +antis +antra +antre +antsy +anura +anvil +anyon +aorta +apace +apage +apaid +apart +apayd +apays +apeak +apeek +apers +apert +apery +apgar +aphid +aphis +apian +aping +apiol +apish +apism +apnea +apode +apods +apoop +aport +appal +appay +appel +apple +apply +appro +appui +appuy +apres +apron +apses +apsis +apsos +apted +apter +aptly +aquae +aquas +araba +araks +arame +arars +arbas +arbor +arced +archi +arcos +arcus +ardeb +ardor +ardri +aread +areae +areal +arear +areas +areca +aredd +arede +arefy +areic +arena +arene +arepa +arere +arete +arets +arett +argal +argan +argil +argle +argol +argon +argot +argue +argus +arhat +arias +ariel +ariki +arils +ariot +arise +arish +arked +arled +arles +armed +armer +armet +armil +armor +arnas +arnut +aroba +aroha +aroid +aroma +arose +arpas +arpen +arrah +arras +array +arret +arris +arrow +arroz +arsed +arses +arsey +arsis +arson +artal +artel +artic +artis +artsy +aruhe +arums +arval +arvee +arvos +aryls +asana +ascon +ascot +ascus +asdic +ashed +ashen +ashes +ashet +aside +asked +asker +askew +askoi +askos +aspen +asper +aspic +aspie +aspis +aspro +assai +assam +assay +asses +asset +assez +assot +aster +astir +astun +asura +asway +aswim +asyla +ataps +ataxy +atigi +atilt +atimy +atlas +atman +atmas +atmos +atocs +atoke +atoks +atoll +atoms +atomy +atone +atony +atopy +atria +atrip +attap +attar +attic +atuas +audad +audio +audit +auger +aught +augur +aulas +aulic +auloi +aulos +aumil +aunes +aunts +aunty +aurae +aural +aurar +auras +aurei +aures +auric +auris +aurum +autos +auxin +avail +avale +avant +avast +avels +avens +avers +avert +avgas +avian +avine +avion +avise +aviso +avize +avoid +avows +avyze +await +awake +award +aware +awarn +awash +awato +awave +aways +awdls +aweel +aweto +awful +awing +awmry +awned +awner +awoke +awols +awork +axels +axial +axile +axils +axing +axiom +axion +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 +azure +azurn +azury +azygy +azyme +azyms +baaed +baals +babas +babel +babes +babka +baboo +babul +babus +bacca +bacco +baccy +bacha +bachs +backs +bacon +baddy +badge +badly +baels +baffs +baffy +bafts +bagel +baggy +baghs +bagie +bahts +bahus +bahut +bails +bairn +baisa +baith +baits +baiza +baize +bajan +bajra +bajri +bajus +baked +baken +baker +bakes +bakra +balas +balds +baldy +baled +baler +bales +balks +balky +balls +bally +balms +balmy +baloo +balsa +balti +balun +balus +bambi +banak +banal +banco +bancs +banda +bandh +bands +bandy +baned +banes +bangs +bania +banjo +banks +banns +bants +bantu +banty +banya +bapus +barbe +barbs +barby +barca +barde +bardo +bards +bardy +bared +barer +bares +barfi +barfs +barge +baric +barks +barky +barms +barmy +barns +barny +baron +barps +barra +barre +barro +barry +barye +basal +basan +based +basen +baser +bases +basho +basic +basij +basil +basin +basis +basks +bason +basse +bassi +basso +bassy +basta +baste +basti +basto +basts +batch +bated +bates +bathe +baths +batik +baton +batta +batts +battu +batty +bauds +bauks +baulk +baurs +bavin +bawds +bawdy +bawks +bawls +bawns +bawrs +bawty +bayed +bayer +bayes +bayle +bayou +bayts +bazar +bazoo +beach +beads +beady +beaks +beaky +beals +beams +beamy +beano +beans +beany +beard +beare +bears +beast +beath +beats +beaty +beaus +beaut +beaux +bebop +becap +becke +becks +bedad +bedel +bedes +bedew +bedim +bedye +beech +beedi +beefs +beefy +beeps +beers +beery +beets +befit +befog +begad +began +begar +begat +begem +beget +begin +begot +begum +begun +beige +beigy +being +beins +bekah +belah +belar +belay +belch +belee +belga +belie +belle +bells +belly +belon +below +belts +bemad +bemas +bemix +bemud +bench +bends +bendy +benes +benet +benga +benis +benne +benni +benny +bento +bents +benty +bepat +beray +beres +beret +bergs +berko +berks +berme +berms +berob +berry +berth +beryl +besat +besaw +besee +beses +beset +besit +besom +besot +besti +bests +betas +beted +betel +betes +beths +betid +beton +betta +betty +bevel +bever +bevor +bevue +bevvy +bewet +bewig +bezel +bezes +bezil +bezzy +bhais +bhaji +bhang +bhats +bhels +bhoot +bhuna +bhuts +biach +biali +bialy +bibbs +bibes +bible +biccy +bicep +bices +biddy +bided +bider +bides +bidet +bidis +bidon +bield +biers +biffo +biffs +biffy +bifid +bigae +biggs +biggy +bigha +bight +bigly +bigos +bigot +bijou +biked +biker +bikes +bikie +bilbo +bilby +biled +biles +bilge +bilgy +bilks +bills +billy +bimah +bimas +bimbo +binal +bindi +binds +biner +bines +binge +bingo +bings +bingy +binit +binks +bints +biogs +biome +biont +biota +biped +bipod +birch +birds +birks +birle +birls +biros +birrs +birse +birsy +birth +bises +bisks +bisom +bison +bitch +biter +bites +bitos +bitou +bitsy +bitte +bitts +bitty +bivia +bivvy +bizes +bizzo +bizzy +blabs +black +blade +blads +blady +blaer +blaes +blaff +blags +blahs +blain +blame +blams +bland +blank +blare +blart +blase +blash +blast +blate +blats +blatt +blaud +blawn +blaws +blays +blaze +bleak +blear +bleat +blebs +blech +bleed +bleep +blees +blend +blent +blert +bless +blest +blets +bleys +blimp +blimy +blind +bling +blini +blink +blins +bliny +blips +bliss +blist +blite +blits +blitz +blive +bloat +blobs +block +blocs +blogs +bloke +blond +blood +blook +bloom +bloop +blore +blots +blown +blows +blowy +blubs +blude +bluds +bludy +blued +bluer +blues +bluet +bluey +bluff +bluid +blume +blunk +blunt +blurb +blurs +blurt +blush +blype +boabs +boaks +board +boars +boart +boast +boats +bobac +bobak +bobas +bobby +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 +boney +bongo +bongs +bonie +bonks +bonne +bonny +bonus +bonza +bonze +booai +booay +boobs +booby +boody +booed +boofy +boogy +boohs +books +booky +bools +booms +boomy +boong +boons +boord +boors +boose +boost +booth +boots +booty +booze +boozy +boppy +borak +boral +boras +borax +borde +bords +bored +boree +borel +borer +bores +borgo +boric +borks +borms +borna +borne +boron +borts +borty +bortz +bosie +bosks +bosky +bosom +boson +bossy +bosun +botas +botch +botel +botes +bothy +botte +botts +botty +bouge +bough +bouks +boule +boult +bound +bouns +bourd +bourg +bourn +bouse +bousy +bouts +bovid +bowat +bowed +bowel +bower +bowes +bowet +bowie +bowls +bowne +bowrs +bowse +boxed +boxen +boxer +boxes +boxla +boxty +boyar +boyau +boyed +boyfs +boygs +boyla +boyos +boysy +bozos +braai +brace +brach +brack +bract +brads +braes +brags +braid +brail +brain +brake +braks +braky +brame +brand +brane +brank +brans +brant +brash +brass +brast +brats +brava +brave +bravi +bravo +brawl +brawn +braws +braxy +brays +braza +braze +bread +break +bream +brede +breds +breed +breem +breer +brees +breid +breis +breme +brens +brent +brere +brers +breve +brews +breys +briar +bribe +brick +bride +brief +brier +bries +brigs +briki +briks +brill +brims +brine +bring +brink +brins +briny +brios +brise +brisk +briss +brith +brits +britt +brize +broad +broch +brock +brods +brogh +brogs +broil +broke +brome +bromo +bronc +brond +brood +brook +brool +broom +broos +brose +brosy +broth +brown +brows +brugh +bruin +bruit +brule +brume +brung +brunt +brush +brusk +brust +brute +bruts +buats +buaze +bubal +bubas +bubba +bubbe +bubby +bubus +buchu +bucko +bucks +bucku +budas +buddy +budge +budis +budos +buffa +buffe +buffi +buffo +buffs +buffy +bufos +bufty +buggy +bugle +buhls +buhrs +buiks +build +built +buist +bukes +bulbs +bulge +bulgy +bulks +bulky +bulla +bulls +bully +bulse +bumbo +bumfs +bumph +bumps +bumpy +bunas +bunce +bunch +bunco +bunde +bundh +bunds +bundt +bundu +bundy +bungs +bungy +bunia +bunje +bunjy +bunko +bunks +bunns +bunny +bunts +bunty +bunya +buoys +buppy +buran +buras +burbs +burds +buret +burfi +burgh +burgs +burin +burka +burke +burks +burls +burly +burns +burnt +buroo +burps +burqa +burro +burrs +burry +bursa +burse +burst +busby +bused +buses +bushy +busks +busky +bussu +busti +busts +busty +butch +buteo +butes +butle +butoh +butte +butts +butty +butut +butyl +buxom +buyer +buzzy +bwana +bwazi +byded +bydes +byked +bykes +bylaw +byres +byrls +byssi +bytes +byway +caaed +cabal +cabas +cabby +caber +cabin +cable +cabob +caboc +cabre +cacao +cacas +cache +cacks +cacky +cacti +caddy +cadee +cades +cadet +cadge +cadgy +cadie +cadis +cadre +caeca +caese +cafes +caffs +caged +cager +cages +cagey +cagot +cahow +caids +cains +caird +cairn +cajon +cajun +caked +cakes +cakey +calfs +calid +calif +calix +calks +calla +calls +calms +calmy +calos +calpa +calps +calve +calyx +caman +camas +camel +cameo +cames +camis +camos +campi +campo +camps +campy +camus +canal +candy +caned +caneh +caner +canes +cangs +canid +canna +canns +canny +canoe +canon +canso +canst +canto +cants +canty +capas +caped +caper +capes +capex +caphs +capiz +caple +capon +capos +capot +capri +capul +caput +carap +carat +carbo +carbs +carby +cardi +cards +cardy +cared +carer +cares +caret +carex +cargo +carks +carle +carls +carns +carny +carob +carol +carom +caron +carpi +carps +carrs +carry +carse +carta +carte +carts +carve +carvy +casas +casco +cased +cases +casks +casky +caste +casts +casus +catch +cater +cates +catty +cauda +cauks +cauld +caulk +cauls +caums +caups +cauri +causa +cause +cavas +caved +cavel +caver +caves +cavie +cavil +cawed +cawks +caxon +cease +ceaze +cebid +cecal +cecum +cedar +ceded +ceder +cedes +cedis +ceiba +ceili +ceils +celeb +cella +celli +cello +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 +chafe +chaff +chaft +chain +chair +chais +chalk +chals +champ +chams +chana +chang +chank +chant +chaos +chape +chaps +chapt +chara +chard +chare +chark +charm +charr +chars +chart +chary +chase +chasm +chats +chave +chavs +chawk +chaws +chaya +chays +cheap +cheat +check +cheek +cheep +cheer +chefs +cheka +chela +chelp +chemo +chems +chere +chert +chess +chest +cheth +chevy +chews +chewy +chiao +chias +chibs +chica +chich +chick +chico +chics +chide +chief +chiel +chiks +child +chile +chili +chill +chimb +chime +chimo +chimp +china +chine +ching +chink +chino +chins +chips +chirk +chirl +chirm +chiro +chirp +chirr +chirt +chiru +chits +chive +chivs +chivy +chizz +chock +choco +chocs +chode +chogs +choil +choir +choke +choko +choky +chola +choli +cholo +chomp +chons +choof +chook +choom +choon +chops +chord +chore +chose +chota +chott +chout +choux +chowk +chows +chubs +chuck +chufa +chuff +chugs +chump +chums +chunk +churl +churn +churr +chuse +chute +chuts +chyle +chyme +chynd +cibol +cided +cider +cides +ciels +cigar +ciggy +cilia +cills +cimar +cimex +cinch +cinct +cines +cinqs +cions +cippi +circa +circs +cires +cirls +cirri +cisco +cissy +cists +cital +cited +citer +cites +cives +civet +civic +civie +civil +civvy +clach +clack +clade +clads +claes +clags +claim +clame +clamp +clams +clang +clank +clans +claps +clapt +claro +clart +clary +clash +clasp +class +clast +clats +claut +clave +clavi +claws +clays +clean +clear +cleat +cleck +cleek +cleep +clefs +cleft +clegs +cleik +clems +clepe +clept +clerk +cleve +clews +click +clied +clies +cliff +clift +climb +clime +cline +cling +clink +clint +clipe +clips +clipt +clits +cloak +cloam +clock +clods +cloff +clogs +cloke +clomb +clomp +clone +clonk +clons +cloop +cloot +clops +close +clote +cloth +clots +cloud +clour +clous +clout +clove +clown +clows +cloye +cloys +cloze +clubs +cluck +clued +clues +cluey +clump +clung +clunk +clype +cnida +coach +coact +coady +coala +coals +coaly +coapt +coarb +coast +coate +coati +coats +cobbs +cobby +cobia +coble +cobra +cobza +cocas +cocci +cocco +cocks +cocky +cocoa +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 +colon +color +colts +colza +comae +comal +comas +combe +combi +combo +combs +comby +comer +comes +comet +comfy +comic +comix +comma +commo +comms +commy +compo +comps +compt +comte +comus +conch +condo +coned +cones +coney +confs +conga +conge +congo +conia +conic +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 +copse +copsy +coqui +coral +coram +corbe +corby +cords +cored +corer +cores +corey +corgi +coria +corks +corky +corms +corni +corno +corns +cornu +corny +corps +corse +corso +cosec +cosed +coses +coset +cosey +cosie +costa +coste +costs +cotan +coted +cotes +coths +cotta +cotts +couch +coude +cough +could +count +coupe +coups +courb +courd +coure +cours +court +couta +couth +coved +coven +cover +coves +covet +covey +covin +cowal +cowan +cowed +cower +cowks +cowls +cowps +cowry +coxae +coxal +coxed +coxes +coxib +coyau +coyed +coyer +coyly +coypu +cozed +cozen +cozes +cozey +cozie +craal +crabs +crack +craft +crags +craic +craig +crake +crame +cramp +crams +crane +crank +crans +crape +craps +crapy +crare +crash +crass +crate +crave +crawl +craws +crays +craze +crazy +creak +cream +credo +creds +creed +creek +creel +creep +crees +creme +crems +crena +crepe +creps +crept +crepy +cress +crest +crewe +crews +crias +cribs +crick +cried +crier +cries +crime +crimp +crims +crine +crios +cripe +crips +crise +crisp +crith +crits +croak +croci +crock +crocs +croft +crogs +cromb +crome +crone +cronk +crons +crony +crook +crool +croon +crops +crore +cross +crost +croup +crout +crowd +crown +crows +croze +cruck +crude +crudo +cruds +crudy +cruel +crues +cruet +cruft +crumb +crump +crunk +cruor +crura +cruse +crush +crust +crusy +cruve +crwth +cryer +crypt +ctene +cubby +cubeb +cubed +cuber +cubes +cubic +cubit +cuddy +cuffo +cuffs +cuifs +cuing +cuish +cuits +cukes +culch +culet +culex +culls +cully +culms +culpa +culti +cults +culty +cumec +cumin +cundy +cunei +cunit +cunts +cupel +cupid +cuppa +cuppy +curat +curbs +curch +curds +curdy +cured +curer +cures +curet +curfs +curia +curie +curio +curli +curls +curly +curns +curny +currs +curry +curse +cursi +curst +curve +curvy +cusec +cushy +cusks +cusps +cuspy +cusso +cusum +cutch +cuter +cutes +cutey +cutie +cutin +cutis +cutto +cutty +cutup +cuvee +cuzes +cwtch +cyano +cyans +cyber +cycad +cycas +cycle +cyclo +cyder +cylix +cymae +cymar +cymas +cymes +cymol +cynic +cysts +cytes +cyton +czars +daals +dabba +daces +dacha +dacks +dadah +dadas +daddy +dados +daffs +daffy +dagga +daggy +dagos +dahls +daiko +daily +daine +daint +dairy +daisy +daker +daled +dales +dalis +dalle +dally +dalts +daman +damar +dames +damme +damns +damps +dampy +dance +dancy +dandy +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 +datum +daube +daubs +dauby +dauds +dault +daunt +daurs +dauts +daven +davit +dawah +dawds +dawed +dawen +dawks +dawns +dawts +dayan +daych +daynt +dazed +dazer +dazes +deads +deair +deals +dealt +deans +deare +dearn +dears +deary +deash +death +deave +deaws +deawy +debag +debar +debby +debel +debes +debit +debts +debud +debug +debur +debus +debut +debye +decad +decaf +decal +decan +decay +decko +decks +decor +decos +decoy +decry +dedal +deeds +deedy +deely +deems +deens +deeps +deere +deers +deets +deeve +deevs +defat +defer +deffo +defis +defog +degas +degum +degus +deice +deids +deify +deign +deils +deism +deist +deity +deked +dekes +dekko +delay +deled +deles +delfs +delft +delis +dells +delly +delos +delph +delta +delts +delve +deman +demes +demic +demit +demob +demoi +demon +demos +dempt +demur +denar +denay +dench +denes +denet +denim +denis +dense +dents +deoxy +depot +depth +derat +deray +derby +dered +deres +derig +derma +derms +derns +derny +deros +derro +derry +derth +dervs +desex +deshi +desis +desks +desse +deter +detox +deuce +devas +devel +devil +devis +devon +devos +devot +dewan +dewar +dewax +dewed +dexes +dexie +dhaba +dhaks +dhals +dhikr +dhobi +dhole +dholl +dhols +dhoti +dhows +dhuti +diact +dials +diane +diary +diazo +dibbs +diced +dicer +dices +dicey +dicht +dicks +dicky +dicot +dicta +dicts +dicty +diddy +didie +didos +didst +diebs +diels +diene +diets +diffs +dight +digit +dikas +diked +diker +dikes +dikey +dildo +dilli +dills +dilly +dimbo +dimer +dimes +dimly +dimps +dinar +dined +diner +dines +dinge +dingo +dings +dingy +dinic +dinks +dinky +dinna +dinos +dints +diode +diols +diota +dippy +dipso +diram +direr +dirge +dirke +dirks +dirls +dirts +dirty +disas +disci +disco +discs +dishy +disks +disme +dital +ditas +ditch +dited +dites +ditsy +ditto +ditts +ditty +ditzy +divan +divas +dived +diver +dives +divis +divna +divos +divot +divvy +diwan +dixie +dixit +diyas +dizen +dizzy +djinn +djins +doabs +doats +dobby +dobes +dobie +dobla +dobra +dobro +docht +docks +docos +docus +doddy +dodge +dodgy +dodos +doeks +doers +doest +doeth +doffs +dogan +doges +dogey +doggo +doggy +dogie +dogma +dohyo +doilt +doily +doing +doits +dojos +dolce +dolci +doled +doles +dolia +dolls +dolly +dolma +dolor +dolos +dolts +domal +domed +domes +domic +donah +donas +donee +doner +donga +dongs +donko +donna +donne +donny +donor +donsy +donut +doobs +dooce +doody +dooks +doole +dools +dooly +dooms +doomy +doona +doorn +doors +doozy +dopas +doped +doper +dopes +dopey +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 +doubt +douce +doucs +dough +douks +doula +douma +doums +doups +doura +douse +douts +doved +doven +dover +doves +dovie +dowar +dowds +dowdy +dowed +dowel +dower +dowie +dowle +dowls +dowly +downa +downs +downy +dowps +dowry +dowse +dowts +doxed +doxes +doxie +doyen +doyly +dozed +dozen +dozer +dozes +drabs +drack +draco +draff +draft +drags +drail +drain +drake +drama +drams +drank +drant +drape +draps +drats +drave +drawl +drawn +draws +drays +dread +dream +drear +dreck +dreed +dreer +drees +dregs +dreks +drent +drere +dress +drest +dreys +dribs +drice +dried +drier +dries +drift +drill +drily +drink +drips +dript +drive +droid +droil +droit +droke +drole +droll +drome +drone +drony +droob +droog +drook +drool +droop +drops +dropt +dross +drouk +drove +drown +drows +drubs +drugs +druid +drums +drunk +drupe +druse +drusy +druxy +dryad +dryas +dryer +dryly +dsobo +dsomo +duads +duals +duans +duars +dubbo +ducal +ducat +duces +duchy +ducks +ducky +ducts +duddy +duded +dudes +duels +duets +duett +duffs +dufus +duing +duits +dukas +duked +dukes +dukka +dulce +dules +dulia +dulls +dully +dulse +dumas +dumbo +dumbs +dumka +dumky +dummy +dumps +dumpy +dunam +dunce +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 +dusky +dusts +dusty +dutch +duvet +duxes +dwaal +dwale +dwalm +dwams +dwang +dwarf +dwaum +dweeb +dwell +dwelt +dwile +dwine +dyads +dyers +dying +dyked +dykes +dykey +dykon +dynel +dynes +dzhos +eager +eagle +eagre +ealed +eales +eaned +eards +eared +earls +early +earns +earnt +earst +earth +eased +easel +easer +eases +easle +easts +eaten +eater +eathe +eaved +eaves +ebbed +ebbet +ebons +ebony +ebook +ecads +eched +eches +echos +eclat +ecrus +edema +edged +edger +edges +edict +edify +edile +edits +educe +educt +eejit +eensy +eerie +eeven +eevns +effed +egads +egers +egest +eggar +egged +egger +egmas +egret +ehing +eider +eidos +eight +eigne +eiked +eikon +eilds +eisel +eject +ejido +eking +ekkas +elain +eland +elans +elate +elbow +elchi +elder +eldin +elect +elegy +elemi +elfed +elfin +eliad +elide +elint +elite +elmen +eloge +elogy +eloin +elope +elops +elpee +elsin +elude +elute +elvan +elven +elver +elves +emacs +email +embar +embay +embed +ember +embog +embow +embox +embus +emcee +emeer +emend +emerg +emery +emeus +emics +emirs +emits +emmas +emmer +emmet +emmew +emmys +emoji +emong +emote +emove +empts +empty +emule +emure +emyde +emyds +enact +enarm +enate +ended +ender +endew +endow +endue +enema +enemy +enews +enfix +eniac +enjoy +enlit +enmew +ennog +ennui +enoki +enols +enorm +enows +enrol +ensew +ensky +ensue +enter +entia +entry +enure +enurn +envoi +envoy +enzym +eorls +eosin +epact +epees +ephah +ephas +ephod +ephor +epics +epoch +epode +epopt +epoxy +epris +equal +eques +equid +equip +erase +erbia +erect +erevs +ergon +ergos +ergot +erhus +erica +erick +erics +ering +erned +ernes +erode +erose +erred +error +erses +eruct +erugo +erupt +eruvs +erven +ervil +escar +escot +esile +eskar +esker +esnes +essay +esses +ester +estoc +estop +estro +etage +etape +etats +etens +ethal +ether +ethic +ethne +ethos +ethyl +etics +etnas +ettin +ettle +etude +etuis +etwee +etyma +eughs +euked +eupad +euros +eusol +evade +evens +event +evert +every +evets +evhoe +evict +evils +evite +evohe +evoke +ewers +ewest +ewhow +ewked +exact +exalt +exams +excel +exeat +execs +exeem +exeme +exert +exfil +exies +exile +exine +exing +exist +exits +exode +exome +exons +expat +expel +expos +extol +extra +exude +exuls +exult +exurb +eyass +eyers +eying +eyots +eyras +eyres +eyrie +eyrir +ezine +fabby +fable +faced +facer +faces +facet +facia +facta +facts +faddy +faded +fader +fades +fadge +fados +faena +faery +faffs +faffy +faggy +fagin +fagot +faiks +fails +faine +fains +faint +fairs +fairy +faith +faked +faker +fakes +fakey +fakie +fakir +falaj +falls +false +famed +fames +fanal +fancy +fands +fanes +fanga +fango +fangs +fanks +fanny +fanon +fanos +fanum +faqir +farad +farce +farci +farcy +fards +fared +farer +fares +farle +farls +farms +faros +farro +farse +farts +fasci +fasti +fasts +fatal +fated +fates +fatly +fatso +fatty +fatwa +faugh +fauld +fault +fauna +fauns +faurd +fauts +fauve +favas +favel +faver +faves +favor +favus +fawns +fawny +faxed +faxes +fayed +fayer +fayne +fayre +fazed +fazes +feals +feare +fears +feart +fease +feast +feats +feaze +fecal +feces +fecht +fecit +fecks +fedex +feebs +feeds +feels +feens +feers +feese +feeze +fehme +feign +feint +feist +felch +felid +fella +fells +felly +felon +felts +felty +femal +femes +femme +femmy +femur +fence +fends +fendy +fenis +fenks +fenny +fents +feods +feoff +feral +ferer +feres +feria +ferly +fermi +ferms +ferns +ferny +ferry +fesse +festa +fests +festy +fetal +fetas +fetch +feted +fetes +fetid +fetor +fetta +fetts +fetus +fetwa +feuar +feuds +feued +fever +fewer +feyed +feyer +feyly +fezes +fezzy +fiars +fiats +fiber +fibre +fibro +fices +fiche +fichu +ficin +ficos +ficus +fides +fidge +fidos +fiefs +field +fiend +fient +fiere +fiers +fiery +fiest +fifed +fifer +fifes +fifis +fifth +fifty +figgy +fight +figos +fiked +fikes +filar +filch +filed +filer +files +filet +filii +filks +fille +fillo +fills +filly +filmi +films +filmy +filos +filth +filum +final +finca +finch +finds +fined +finer +fines +finis +finks +finny +finos +fiord +fiqhs +fique +fired +firer +fires +firie +firks +firms +firns +firry +first +firth +fiscs +fishy +fisks +fists +fisty +fitch +fitly +fitna +fitte +fitts +fiver +fives +fixed +fixer +fixes +fixit +fizzy +fjeld +fjord +flabs +flack +flaff +flags +flail +flair +flake +flaks +flaky +flame +flamm +flams +flamy +flane +flank +flans +flaps +flare +flary +flash +flask +flats +flava +flawn +flaws +flawy +flaxy +flays +fleam +fleas +fleck +fleek +fleer +flees +fleet +flegs +fleme +flesh +fleur +flews +flexi +flexo +fleys +flick +flics +flied +flier +flies +flimp +flims +fling +flint +flips +flirs +flirt +flisk +flite +flits +flitt +float +flobs +flock +flocs +floes +flogs +flong +flood +floor +flops +flora +flors +flory +flosh +floss +flota +flote +flour +flout +flown +flows +flubs +flued +flues +fluey +fluff +fluid +fluke +fluky +flume +flump +flung +flunk +fluor +flurr +flush +flute +fluty +fluyt +flyby +flyer +flype +flyte +foals +foams +foamy +focal +focus +foehn +fogey +foggy +fogie +fogle +fogou +fohns +foids +foils +foins +foist +folds +foley +folia +folic +folie +folio +folks +folky +folly +fomes +fonda +fonds +fondu +fones +fonly +fonts +foods +foody +fools +foots +footy +foram +foray +forbs +forby +force +fordo +fords +forel +fores +forex +forge +forgo +forks +forky +forme +forms +forte +forth +forts +forty +forum +forza +forze +fossa +fosse +fouat +fouds +fouer +fouet +foule +fouls +found +fount +fours +fouth +fovea +fowls +fowth +foxed +foxes +foxie +foyer +foyle +foyne +frabs +frack +fract +frags +frail +fraim +frame +franc +frank +frape +fraps +frass +frate +frati +frats +fraud +fraus +frays +freak +freed +freer +frees +freet +freit +fremd +frena +freon +frere +fresh +frets +friar +fribs +fried +frier +fries +frigs +frill +frise +frisk +frist +frith +frits +fritt +fritz +frize +frizz +frock +froes +frogs +frond +frons +front +frore +frorn +frory +frosh +frost +froth +frown +frows +frowy +froze +frugs +fruit +frump +frush +frust +fryer +fubar +fubby +fubsy +fucks +fucus +fuddy +fudge +fudgy +fuels +fuero +fuffs +fuffy +fugal +fuggy +fugie +fugio +fugle +fugly +fugue +fugus +fujis +fulls +fully +fumed +fumer +fumes +fumet +fundi +funds +fundy +fungi +fungo +fungs +funks +funky +funny +fural +furan +furca +furls +furol +furor +furrs +furry +furth +furze +furzy +fused +fusee +fusel +fuses +fusil +fusks +fussy +fusts +fusty +futon +fuzed +fuzee +fuzes +fuzil +fuzzy +fyces +fyked +fykes +fyles +fyrds +fytte +gabba +gabby +gable +gaddi +gades +gadge +gadid +gadis +gadje +gadjo +gadso +gaffe +gaffs +gaged +gager +gages +gaids +gaily +gains +gairs +gaita +gaits +gaitt +gajos +galah +galas +galax +galea +galed +gales +galls +gally +galop +galut +galvo +gamas +gamay +gamba +gambe +gambo +gambs +gamed +gamer +games +gamey +gamic +gamin +gamma +gamme +gammy +gamps +gamut +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 +gassy +gasts +gatch +gated +gater +gates +gaths +gator +gauch +gaucy +gauds +gaudy +gauge +gauje +gault +gaums +gaumy +gaunt +gaups +gaurs +gauss +gauze +gauzy +gavel +gavot +gawcy +gawds +gawks +gawky +gawps +gawsy +gayal +gayer +gayly +gazal +gazar +gazed +gazer +gazes +gazon +gazoo +geals +geans +geare +gears +geats +gebur +gecko +gecks +geeks +geeky +geeps +geese +geest +geist +geits +gelds +gelee +gelid +gelly +gelts +gemel +gemma +gemmy +gemot +genal +genas +genes +genet +genic +genie +genii +genip +genny +genoa +genom +genre +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 +ghost +ghoul +ghyll +giant +gibed +gibel +giber +gibes +gibli +gibus +giddy +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 +gipsy +girds +girls +girly +girns +giron +giros +girrs +girsh +girth +girts +gismo +gisms +gists +gitch +gites +giust +gived +given +giver +gives +gizmo +glace +glade +glads +glady +glaik +glair +glams +gland +glans +glare +glary +glass +glaum +glaur +glaze +glazy +gleam +glean +gleba +glebe +gleby +glede +gleds +gleed +gleek +glees +gleet +gleis +glens +glent +gleys +glial +glias +glibs +glide +gliff +glift +glike +glime +glims +glint +glisk +glits +glitz +gloam +gloat +globe +globi +globs +globy +glode +glogg +gloms +gloom +gloop +glops +glory +gloss +glost +glout +glove +glows +gloze +glued +gluer +glues +gluey +glugs +glume +glums +gluon +glute +gluts +glyph +gnarl +gnarr +gnars +gnash +gnats +gnawn +gnaws +gnome +gnows +goads +goafs +goals +goary +goats +goaty +goban +gobar +gobbi +gobbo +gobby +gobis +gobos +godet +godly +godso +goels +goers +goest +goeth +goety +gofer +goffs +gogga +gogos +goier +going +gojis +golds +goldy +golem +goles +golfs +golly +golpe +golps +gombo +gomer +gompa +gonad +gonch +gonef +goner +gongs +gonia +gonif +gonks +gonna +gonof +gonys +gonzo +gooby +goods +goody +gooey +goofs +goofy +googs +gooks +gooky +goold +gools +gooly +goons +goony +goops +goopy +goors +goory +goose +goosy +gopak +gopik +goral +goras +gored +gores +gorge +goris +gorms +gormy +gorps +gorse +gorsy +gosht +gosse +gotch +goths +gothy +gotta +gouch +gouge +gouks +goura +gourd +gouts +gouty +gowan +gowds +gowfs +gowks +gowls +gowns +goxes +goyim +goyle +graal +grabs +grace +grade +grads +graff +graft +grail +grain +graip +grama +grame +gramp +grams +grana +grand +grans +grant +grape +graph +grapy +grasp +grass +grate +grave +gravs +gravy +grays +graze +great +grebe +grebo +grece +greed +greek +green +grees +greet +grege +grego +grein +grens +grese +greve +grews +greys +grice +gride +grids +grief +griff +grift +grigs +grike +grill +grime +grimy +grind +grins +griot +gripe +grips +gript +gripy +grise +grist +grisy +grith +grits +grize +groan +groat +grody +grogs +groin +groks +groma +grone +groof +groom +grope +gross +grosz +grots +grouf +group +grout +grove +grovy +growl +grown +grows +grrls +grrrl +grubs +grued +gruel +grues +grufe +gruff +grume +grump +grund +grunt +gryce +gryde +gryke +grype +grypt +guaco +guana +guano +guans +guard +guars +guava +gucks +gucky +gudes +guess +guest +guffs +gugas +guide +guids +guild +guile +guilt +guimp +guiro +guise +gulag +gular +gulas +gulch +gules +gulet +gulfs +gulfy +gulls +gully +gulph +gulps +gulpy +gumbo +gumma +gummi +gummy +gumps +gundy +gunge +gungy +gunks +gunky +gunny +guppy +guqin +gurdy +gurge +gurls +gurly +gurns +gurry +gursh +gurus +gushy +gusla +gusle +gusli +gussy +gusto +gusts +gusty +gutsy +gutta +gutty +guyed +guyle +guyot +guyse +gwine +gyals +gyans +gybed +gybes +gyeld +gymps +gynae +gynie +gynny +gynos +gyoza +gypos +gyppo +gyppy +gypsy +gyral +gyred +gyres +gyron +gyros +gyrus +gytes +gyved +gyves +haafs +haars +habit +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 +hairy +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 +halve +halwa +hamal +hamba +hamed +hames +hammy +hamza +hanap +hance +hanch +hands +handy +hangi +hangs +hanks +hanky +hansa +hanse +hants +haole +haoma +hapax +haply +happi +happy +hapus +haram +hards +hardy +hared +harem +hares +harim +harks +harls +harms +harns +haros +harps +harpy +harry +harsh +harts +hashy +hasks +hasps +hasta +haste +hasty +hatch +hated +hater +hates +hatha +hauds +haufs +haugh +hauld +haulm +hauls +hault +hauns +haunt +hause +haute +haven +haver +haves +havoc +hawed +hawks +hawms +hawse +hayed +hayer +hayey +hayle +hazan +hazed +hazel +hazer +hazes +heads +heady +heald +heals +heame +heaps +heapy +heard +heare +hears +heart +heast +heath +heats +heave +heavy +heben +hebes +hecht +hecks +heder +hedge +hedgy +heeds +heedy +heels +heeze +hefte +hefts +hefty +heids +heigh +heils +heirs +heist +hejab +hejra +heled +heles +helio +helix +hello +hells +helms +helos +helot +helps +helve +hemal +hemes +hemic +hemin +hemps +hempy +hence +hench +hends +henge +henna +henny +henry +hents +hepar +herbs +herby +herds +heres +herls +herma +herms +herns +heron +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 +hilly +hilts +hilum +hilus +himbo +hinau +hinds +hinge +hings +hinky +hinny +hints +hiois +hiply +hippo +hippy +hired +hiree +hirer +hires +hissy +hists +hitch +hithe +hived +hiver +hives +hizen +hoaed +hoagy +hoard +hoars +hoary +hoast +hobby +hobos +hocks +hocus +hodad +hodja +hoers +hogan +hogen +hoggs +hoghs +hohed +hoick +hoied +hoiks +hoing +hoise +hoist +hokas +hoked +hokes +hokey +hokis +hokku +hokum +holds +holed +holes +holey +holks +holla +hollo +holly +holme +holms +holon +holos +holts +homas +homed +homer +homes +homey +homie +homme +homos +honan +honda +honds +honed +honer +hones +honey +hongi +hongs +honks +honky +honor +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 +horde +horis +horks +horme +horns +horny +horse +horst +horsy +hosed +hosel +hosen +hoser +hoses +hosey +hosta +hosts +hotch +hotel +hoten +hotly +hotty +houff +houfs +hough +hound +houri +hours +house +houts +hovea +hoved +hovel +hoven +hover +hoves +howbe +howdy +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 +human +humas +humfs +humic +humid +humor +humph +humps +humpy +humus +hunch +hunks +hunky +hunts +hurds +hurls +hurly +hurra +hurry +hurst +hurts +hushy +husks +husky +husos +hussy +hutch +hutia +huzza +huzzy +hwyls +hydra +hydro +hyena +hyens +hygge +hying +hykes +hylas +hyleg +hyles +hylic +hymen +hymns +hynde +hyoid +hyped +hyper +hypes +hypha +hyphy +hypos +hyrax +hyson +hythe +iambi +iambs +ibrik +icers +iched +iches +ichor +icier +icily +icing +icker +ickle +icons +ictal +ictic +ictus +idant +ideal +ideas +idees +ident +idiom +idiot +idled +idler +idles +idola +idols +idyll +idyls +iftar +igapo +igged +igloo +iglus +ihram +ikans +ikats +ikons +ileac +ileal +ileum +ileus +iliac +iliad +ilial +ilium +iller +illth +image +imago +imams +imari +imaum +imbar +imbed +imbue +imide +imido +imids +imine +imino +immew +immit +immix +imped +impel +impis +imply +impot +impro +imshi +imshy +inane +inapt +inarm +inbox +inbye +incel +incle +incog +incur +incus +incut +indew +index +india +indie +indol +indow +indri +indue +inept +inerm +inert +infer +infix +infos +infra +ingan +ingle +ingot +inion +inked +inker +inkle +inlay +inlet +inned +inner +innit +inorb +input +inrun +inset +inspo +intel +inter +intil +intis +intra +intro +inula +inure +inurn +inust +invar +inwit +iodic +iodid +iodin +ionic +iotas +ippon +irade +irate +irids +iring +irked +iroko +irone +irons +irony +isbas +ishes +isled +isles +islet +isnae +issei +issue +istle +itchy +items +ither +ivied +ivies +ivory +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 +jaunt +jaups +javas +javel +jawan +jawed +jaxie +jazzy +jeans +jeats +jebel +jedis +jeels +jeely +jeeps +jeers +jeeze +jefes +jeffs +jehad +jehus +jelab +jello +jells +jelly +jembe +jemmy +jenny +jeons +jerid +jerks +jerky +jerry +jesse +jests +jesus +jetes +jeton +jetty +jeune +jewed +jewel +jewie +jhala +jiaos +jibba +jibbs +jibed +jiber +jibes +jiffs +jiffy +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 +joint +joist +joked +joker +jokes +jokey +jokol +joled +joles +jolls +jolly +jolts +jolty +jomon +jomos +jones +jongs +jonty +jooks +joram +jorum +jotas +jotty +jotun +joual +jougs +jouks +joule +jours +joust +jowar +jowed +jowls +jowly +joyed +jubas +jubes +jucos +judas +judge +judgy +judos +jugal +jugum +juice +juicy +jujus +juked +jukes +jukus +julep +jumar +jumbo +jumby +jumps +jumpy +junco +junks +junky +junta +junto +jupes +jupon +jural +jurat +jurel +jures +juror +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 +kappa +kapus +kaput +karas +karat +karks +karma +karns +karoo +karos +karri +karst +karsy +karts +karzy +kasha +kasme +katal +katas +katis +katti +kaugh +kauri +kauru +kaury +kaval +kavas +kawas +kawau +kawed +kayak +kayle +kayos +kazis +kazoo +kbars +kebab +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 +khaki +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 +kinky +kinos +kiore +kiosk +kipes +kippa +kipps +kirby +kirks +kirns +kirri +kisan +kissy +kists +kited +kiter +kites +kithe +kiths +kitty +kitul +kivas +kiwis +klang +klaps +klett +klick +klieg +kliks +klong +kloof +kluge +klutz +knack +knags +knaps +knarl +knars +knaur +knave +knawe +knead +kneed +kneel +knees +knell +knelt +knife +knish +knits +knive +knobs +knock +knoll +knops +knosp +knots +knout +knowe +known +knows +knubs +knurl +knurr +knurs +knuts +koala +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 +krill +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 +label +labia +labis +labor +labra +laced +lacer +laces +lacet +lacey +lacks +laddy +laded +laden +lader +lades +ladle +laers +laevo +lagan +lager +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 +lance +lanch +lande +lands +lanes +lanks +lanky +lants +lapel +lapin +lapis +lapje +lapse +larch +lards +lardy +laree +lares +large +largo +laris +larks +larky +larns +larnt +larum +larva +lased +laser +lases +lassi +lasso +lassu +lassy +lasts +latah +latch +lated +laten +later +latex +lathe +lathi +laths +lathy +latke +latte +latus +lauan +lauch +lauds +laufs +laugh +laund +laura +laval +lavas +laved +laver +laves +lavra +lavvy +lawed +lawer +lawin +lawks +lawns +lawny +laxed +laxer +laxes +laxly +layed +layer +layin +layup +lazar +lazed +lazes +lazos +lazzi +lazzo +leach +leads +leady +leafs +leafy +leaks +leaky +leams +leans +leant +leany +leaps +leapt +leare +learn +lears +leary +lease +leash +least +leats +leave +leavy +leaze +leben +leccy +ledes +ledge +ledgy +ledum +leear +leech +leeks +leeps +leers +leery +leese +leets +leeze +lefte +lefts +lefty +legal +leger +leges +legge +leggo +leggy +legit +lehrs +lehua +leirs +leish +leman +lemed +lemel +lemes +lemma +lemme +lemon +lemur +lends +lenes +lengs +lenis +lenos +lense +lenti +lento +leone +leper +lepid +lepra +lepta +lered +leres +lerps +lesbo +leses +lests +letch +lethe +letup +leuch +leuco +leuds +leugh +levas +levee +level +lever +leves +levin +levis +lewis +lexes +lexis +lezes +lezza +lezzy +liana +liane +liang +liard +liars +liart +libel +liber +libra +libri +lichi +licht +licit +licks +lidar +lidos +liefs +liege +liens +liers +lieus +lieve +lifer +lifes +lifts +ligan +liger +ligge +light +ligne +liked +liken +liker +likes +likin +lilac +lills +lilos +lilts +liman +limas +limax +limba +limbi +limbo +limbs +limby +limed +limen +limes +limey +limit +limma +limns +limos +limpa +limps +linac +linch +linds +lindy +lined +linen +liner +lines +liney +linga +lingo +lings +lingy +linin +links +linky +linns +linny +linos +lints +linty +linum +linux +lions +lipas +lipes +lipid +lipin +lipos +lippy +liras +lirks +lirot +lisks +lisle +lisps +lists +litai +litas +lited +liter +lites +lithe +litho +liths +litre +lived +liven +liver +lives +livid +livor +livre +llama +llano +loach +loads +loafs +loams +loamy +loans +loast +loath +loave +lobar +lobby +lobed +lobes +lobos +lobus +local +loche +lochs +locie +locis +locks +locos +locum +locus +loden +lodes +lodge +loess +lofts +lofty +logan +loges +loggy +logia +logic +logie +login +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 +loopy +loord +loose +loots +loped +loper +lopes +loppy +loral +loran +lords +lordy +lorel +lores +loric +loris +lorry +losed +losel +losen +loser +loses +lossy +lotah +lotas +lotes +lotic +lotos +lotsa +lotta +lotte +lotto +lotus +loued +lough +louie +louis +louma +lound +louns +loupe +loups +loure +lours +loury +louse +lousy +louts +lovat +loved +lover +loves +lovey +lovie +lowan +lowed +lower +lowes +lowly +lownd +lowne +lowns +lowps +lowry +lowse +lowts +loxed +loxes +loyal +lozen +luach +luaus +lubed +lubes +lubra +luces +lucid +lucks +lucky +lucre +ludes +ludic +ludos +luffa +luffs +luged +luger +luges +lulls +lulus +lumas +lumbi +lumen +lumme +lummy +lumps +lumpy +lunar +lunas +lunch +lunes +lunet +lunge +lungi +lungs +lunks +lunts +lupin +lupus +lurch +lured +lurer +lures +lurex +lurgi +lurgy +lurid +lurks +lurry +lurve +luser +lushy +lusks +lusts +lusty +lusus +lutea +luted +luter +lutes +luvvy +luxed +luxer +luxes +lweis +lyams +lyard +lyart +lyase +lycea +lycee +lycra +lying +lymes +lymph +lynch +lynes +lyres +lyric +lysed +lyses +lysin +lysis +lysol +lyssa +lyted +lytes +lythe +lytic +lytta +maaed +maare +maars +mabes +macas +macaw +maced +macer +maces +mache +machi +macho +machs +macks +macle +macon +macro +madam +madge +madid +madly +madre +maerl +mafia +mafic +mages +maggs +magic +magma +magot +magus +mahoe +mahua +mahwa +maids +maiko +maiks +maile +maill +mails +maims +mains +maire +mairs +maise +maist +maize +major +makar +maker +makes +makis +makos +malam +malar +malas +malax +males +malic +malik +malis +malls +malms +malmy +malts +malty +malus +malva +malwa +mamas +mamba +mambo +mamee +mamey +mamie +mamma +mammy +manas +manat +mandi +maneb +maned +maneh +manes +manet +manga +mange +mango +mangs +mangy +mania +manic +manis +manky +manly +manna +manor +manos +manse +manta +manto +manty +manul +manus +mapau +maple +maqui +marae +marah +maras +march +marcs +mardy +mares +marge +margs +maria +marid +marka +marks +marle +marls +marly +marms +maron +maror +marra +marri +marry +marse +marsh +marts +marvy +masas +mased +maser +mases +mashy +masks +mason +massa +masse +massy +masts +masty +masus +matai +match +mated +mater +mates +matey +maths +matin +matlo +matte +matts +matza +matzo +mauby +mauds +mauls +maund +mauri +mausy +mauts +mauve +mauzy +maven +mavie +mavin +mavis +mawed +mawks +mawky +mawns +mawrs +maxed +maxes +maxim +maxis +mayan +mayas +maybe +mayed +mayor +mayos +mayst +mazed +mazer +mazes +mazey +mazut +mbira +meads +meals +mealy +meane +means +meant +meany +meare +mease +meath +meats +meaty +mebos +mecca +mechs +mecks +medal +media +medic +medii +medle +meeds +meers +meets +meffs +meins +meint +meiny +meith +mekka +melas +melba +melds +melee +melic +melik +mells +melon +melts +melty +memes +memos +menad +mends +mened +menes +menge +mengs +mensa +mense +mensh +menta +mento +menus +meous +meows +merch +mercs +mercy +merde +mered +merel +merer +meres +merge +meril +meris +merit +merks +merle +merls +merry +merse +mesal +mesas +mesel +meses +meshy +mesic +mesne +meson +messy +mesto +metal +meted +meter +metes +metho +meths +metic +metif +metis +metol +metre +metro +meuse +meved +meves +mewed +mewls +meynt +mezes +mezze +mezzo +mhorr +miaou +miaow +miasm +miaul +micas +miche +micht +micks +micky +micos +micra +micro +middy +midge +midgy +midis +midst +miens +mieve +miffs +miffy +mifty +miggs +might +mihas +mihis +miked +mikes +mikra +mikva +milch +milds +miler +miles +milfs +milia +milko +milks +milky +mille +mills +milor +milos +milpa +milts +milty +miltz +mimed +mimeo +mimer +mimes +mimic +mimsy +minae +minar +minas +mince +mincy +minds +mined +miner +mines +minge +mings +mingy +minim +minis +minke +minks +minny +minor +minos +mints +minty +minus +mired +mires +mirex +mirid +mirin +mirks +mirky +mirly +miros +mirth +mirvs +mirza +misch +misdo +miser +mises +misgo +misos +missa +missy +mists +misty +mitch +miter +mites +mitis +mitre +mitts +mixed +mixen +mixer +mixes +mixte +mixup +mizen +mizzy +mneme +moans +moats +mobby +mobes +mobey +mobie +moble +mocha +mochi +mochs +mochy +mocks +modal +model +modem +moder +modes +modge +modii +modus +moers +mofos +moggy +mogul +mohel +mohos +mohrs +mohua +mohur +moile +moils +moira +moire +moist +moits +mojos +mokes +mokis +mokos +molal +molar +molas +molds +moldy +moled +moles +molla +molls +molly +molto +molts +molys +momes +momma +mommy +momus +monad +monal +monas +monde +mondo +moner +money +mongo +mongs +monic +monie +monks +monos +monte +month +monty +moobs +mooch +moods +moody +mooed +mooks +moola +mooli +mools +mooly +moong +moons +moony +moops +moors +moory +moose +moots +moove +moped +moper +mopes +mopey +moppy +mopsy +mopus +morae +moral +moras +morat +moray +morel +mores +moria +morne +morns +moron +morph +morra +morro +morse +morts +mosed +moses +mosey +mosks +mosso +mossy +moste +mosts +moted +motel +moten +motes +motet +motey +moths +mothy +motif +motis +motor +motte +motto +motts +motty +motus +motza +mouch +moues +mould +mouls +moult +mound +mount +moups +mourn +mouse +moust +mousy +mouth +moved +mover +moves +movie +mowas +mowed +mower +mowra +moxas +moxie +moyas +moyle +moyls +mozed +mozes +mozos +mpret +mucho +mucic +mucid +mucin +mucks +mucky +mucor +mucro +mucus +muddy +mudge +mudir +mudra +muffs +mufti +mugga +muggs +muggy +muhly +muids +muils +muirs +muist +mujik +mulch +mulct +muled +mules +muley +mulga +mulie +mulla +mulls +mulse +mulsh +mumms +mummy +mumps +mumsy +mumus +munch +munga +munge +mungo +mungs +munis +munts +muntu +muons +mural +muras +mured +mures +murex +murid +murks +murky +murls +murly +murra +murre +murri +murrs +murry +murti +murva +musar +musca +mused +muser +muses +muset +musha +mushy +music +musit +musks +musky +musos +musse +mussy +musth +musts +musty +mutch +muted +muter +mutes +mutha +mutis +muton +mutts +muxed +muxes +muzak +muzzy +mvule +myall +mylar +mynah +mynas +myoid +myoma +myope +myops +myopy +myrrh +mysid +mythi +myths +mythy +myxos +mzees +naams +naans +nabes +nabis +nabks +nabla +nabob +nache +nacho +nacre +nadas +nadir +naeve +naevi +naffs +nagas +naggy +nagor +nahal +naiad +naifs +naiks +nails +naira +nairu +naive +naked +naker +nakfa +nalas +naled +nalla +named +namer +names +namma +namus +nanas +nance +nancy +nandu +nanna +nanny +nanos +nanua +napas +naped +napes +napoo +nappa +nappe +nappy +naras +narco +narcs +nards +nares +naric +naris +narks +narky +narre +nasal +nashi +nasty +natal +natch +nates +natis +natty +nauch +naunt +naval +navar +navel +naves +navew +navvy +nawab +nazes +nazir +nazis +nduja +neafe +neals +neaps +nears +neath +neats +nebek +nebel +necks +neddy +needs +needy +neeld +neele +neemb +neems +neeps +neese +neeze +negro +negus +neifs +neigh +neist +neive +nelis +nelly +nemas +nemns +nempt +nenes +neons +neper +nepit +neral +nerds +nerdy +nerka +nerks +nerol +nerts +nertz +nerve +nervy +nests +netes +netop +netts +netty +neuks +neume +neums +nevel +never +neves +nevus +newbs +newed +newel +newer +newie +newly +newsy +newts +nexts +nexus +ngaio +ngana +ngati +ngoma +ngwee +nicad +nicer +niche +nicht +nicks +nicol +nidal +nided +nides +nidor +nidus +niece +niefs +nieve +nifes +niffs +niffy +nifty +niger +nighs +night +nihil +nikab +nikah +nikau +nills +nimbi +nimbs +nimps +niner +nines +ninja +ninny +ninon +ninth +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 +noble +nobly +nocks +nodal +noddy +nodes +nodus +noels +noggs +nohow +noils +noily +noint +noirs +noise +noisy +noles +nolls +nolos +nomad +nomas +nomen +nomes +nomic +nomoi +nomos +nonas +nonce +nones +nonet +nongs +nonis +nonny +nonyl +noobs +nooit +nooks +nooky +noons +noops +noose +nopal +noria +noris +norks +norma +norms +north +nosed +noser +noses +nosey +notal +notch +noted +noter +notes +notum +nould +noule +nouls +nouns +nouny +noups +novae +novas +novel +novum +noway +nowed +nowls +nowts +nowty +noxal +noxes +noyau +noyed +noyes +nubby +nubia +nucha +nuddy +nuder +nudes +nudge +nudie +nudzh +nuffs +nugae +nuked +nukes +nulla +nulls +numbs +numen +nummy +nunny +nurds +nurdy +nurls +nurrs +nurse +nutso +nutsy +nutty +nyaff +nyala +nying +nylon +nymph +nyssa +oaked +oaken +oaker +oakum +oared +oases +oasis +oasts +oaten +oater +oaths +oaves +obang +obeah +obeli +obese +obeys +obias +obied +obiit +obits +objet +oboes +obole +oboli +obols +occam +occur +ocean +ocher +oches +ochre +ochry +ocker +ocrea +octad +octal +octan +octas +octet +octyl +oculi +odahs +odals +odder +oddly +odeon +odeum +odism +odist +odium +odors +odour +odyle +odyls +ofays +offal +offed +offer +offie +oflag +often +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 +olden +older +oldie +oleic +olein +olent +oleos +oleum +olios +olive +ollas +ollav +oller +ollie +ology +olpae +olpes +omasa +omber +ombre +ombus +omega +omens +omers +omits +omlah +omovs +omrah +oncer +onces +oncet +oncus +onely +oners +onery +onion +onium +onkus +onlay +onned +onset +ontic +oobit +oohed +oomph +oonts +ooped +oorie +ooses +ootid +oozed +oozes +opahs +opals +opens +opepe +opera +opine +oping +opium +oppos +opsin +opted +opter +optic +orach +oracy +orals +orang +orant +orate +orbed +orbit +orcas +orcin +order +ordos +oread +orfes +organ +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 +other +ottar +otter +ottos +oubit +oucht +ouens +ought +ouija +oulks +oumas +ounce +oundy +oupas +ouped +ouphe +ouphs +ourie +ousel +ousts +outby +outdo +outed +outer +outgo +outre +outro +outta +ouzel +ouzos +ovals +ovary +ovate +ovels +ovens +overs +overt +ovine +ovist +ovoid +ovoli +ovolo +ovule +owche +owies +owing +owled +owler +owlet +owned +owner +owres +owrie +owsen +oxbow +oxers +oxeye +oxide +oxids +oxies +oxime +oxims +oxlip +oxter +oyers +ozeki +ozone +ozzie +paals +paans +pacas +paced +pacer +paces +pacey +pacha +packs +pacos +pacta +pacts +paddy +padis +padle +padma +padre +padri +paean +paedo +paeon +pagan +paged +pager +pages +pagle +pagod +pagri +paiks +pails +pains +paint +paire +pairs +paisa +paise +pakka +palas +palay +palea +paled +paler +pales +palet +palis +palki +palla +palls +pally +palms +palmy +palpi +palps +palsa +palsy +pampa +panax +pance +panda +pands +pandy +paned +panel +panes +panga +pangs +panic +panim +panko +panne +panni +pansy +panto +pants +panty +paoli +paolo +papal +papas +papaw +paper +papes +pappi +pappy +parae +paras +parch +pardi +pards +pardy +pared +paren +pareo +parer +pares +pareu +parev +parge +pargo +paris +parka +parki +parks +parky +parle +parly +parma +parol +parps +parra +parrs +parry +parse +parti +parts +party +parve +parvo +paseo +pases +pasha +pashm +paska +paspy +passe +pasta +paste +pasts +pasty +patch +pated +paten +pater +pates +paths +patin +patio +patka +patly +patsy +patte +patty +patus +pauas +pauls +pause +pavan +paved +paven +paver +paves +pavid +pavin +pavis +pawas +pawaw +pawed +pawer +pawks +pawky +pawls +pawns +paxes +payed +payee +payer +payor +paysd +peace +peach +peage +peags +peaks +peaky +peals +peans +peare +pearl +pears +peart +pease +peats +peaty +peavy +peaze +pebas +pecan +pechs +pecke +pecks +pecky +pedal +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 +penal +pence +pends +pendu +pened +penes +pengo +penie +penis +penks +penna +penne +penni +penny +pents +peons +peony +pepla +pepos +peppy +pepsi +perai +perce +perch +percs +perdu +perdy +perea +peres +peril +peris +perks +perky +perms +perns +perog +perps +perry +perse +perst +perts +perve +pervo +pervs +pervy +pesky +pesos +pesto +pests +pesty +petal +petar +peter +petit +petre +petri +petti +petto +petty +pewee +pewit +peyse +phage +phang +phare +pharm +phase +pheer +phene +pheon +phese +phial +phish +phizz +phlox +phoca +phone +phono +phons +phony +photo +phots +phpht +phuts +phyla +phyle +piani +piano +pians +pibal +pical +picas +piccy +picks +picky +picot +picra +picul +piece +piend +piers +piert +pieta +piets +piety +piezo +piggy +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 +pilot +pilow +pilum +pilus +pimas +pimps +pinas +pinch +pined +pines +piney +pingo +pings +pinko +pinks +pinky +pinna +pinny +pinon +pinot +pinta +pinto +pints +pinup +pions +piony +pious +pioye +pioys +pipal +pipas +piped +piper +pipes +pipet +pipis +pipit +pippy +pipul +pique +pirai +pirls +pirns +pirog +pisco +pises +pisky +pisos +pissy +piste +pitas +pitch +piths +pithy +piton +pitot +pitta +piums +pivot +pixel +pixes +pixie +pized +pizes +pizza +plaas +place +plack +plage +plaid +plain +plait +plane +plank +plans +plant +plaps +plash +plasm +plast +plate +plats +platt +platy +playa +plays +plaza +plead +pleas +pleat +plebe +plebs +plena +pleon +plesh +plews +plica +plied +plier +plies +plims +pling +plink +ploat +plods +plong +plonk +plook +plops +plots +plotz +plouk +plows +ploye +ploys +pluck +plues +pluff +plugs +plumb +plume +plump +plums +plumy +plunk +pluot +plush +pluto +plyer +poach +poaka +poake +poboy +pocks +pocky +podal +poddy +podex +podge +podgy +podia +poems +poeps +poesy +poets +pogey +pogge +pogos +pohed +poilu +poind +point +poise +pokal +poked +poker +pokes +pokey +pokie +polar +poled +poler +poles +poley +polio +polis +polje +polka +polks +polls +polly +polos +polts +polyp +polys +pombe +pomes +pommy +pomos +pomps +ponce +poncy +ponds +pones +poney +ponga +pongo +pongs +pongy +ponks +ponts +ponty +ponzu +pooch +poods +pooed +poofs +poofy +poohs +pooja +pooka +pooks +pools +poons +poops +poopy +poori +poort +poots +poove +poovy +popes +poppa +poppy +popsy +porae +poral +porch +pored +porer +pores +porge +porgy +porin +porks +porky +porno +porns +porny +porta +ports +porty +posed +poser +poses +posey +posho +posit +posse +posts +potae +potch +poted +potes +potin +potoo +potsy +potto +potts +potty +pouch +pouff +poufs +pouke +pouks +poule +poulp +poult +pound +poupe +poupt +pours +pouts +pouty +powan +power +powin +pownd +powns +powny +powre +poxed +poxes +poynt +poyou +poyse +pozzy +praam +prads +prahu +prams +prana +prang +prank +praos +prase +prate +prats +pratt +praty +praus +prawn +prays +predy +preed +preen +prees +preif +prems +premy +prent +preon +preop +preps +presa +prese +press +prest +preve +prexy +preys +prial +price +prick +pricy +pride +pried +prief +prier +pries +prigs +prill +prima +prime +primi +primo +primp +prims +primy +prink +print +prion +prior +prise +prism +priss +privy +prize +proas +probe +probs +prods +proem +profs +progs +proin +proke +prole +proll +promo +proms +prone +prong +pronk +proof +props +prore +prose +proso +pross +prost +prosy +proto +proud +proul +prove +prowl +prows +proxy +proyn +prude +prune +prunt +pruta +pryer +pryse +psalm +pseud +pshaw +psion +psoae +psoai +psoas +psora +psych +psyop +pubco +pubes +pubic +pubis +pucan +pucer +puces +pucka +pucks +puddy +pudge +pudgy +pudic +pudor +pudsy +pudus +puers +puffa +puffs +puffy +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 +pulpy +pulse +pulus +pumas +pumie +pumps +punas +punce +punch +punga +pungs +punji +punka +punks +punky +punny +punto +punts +punty +pupae +pupal +pupas +pupil +puppy +pupus +purda +pured +puree +purer +pures +purge +purin +puris +purls +purpy +purrs +purse +pursy +purty +puses +pushy +pusle +pussy +putid +puton +putti +putto +putts +putty +puzel +pwned +pyats +pyets +pygal +pygmy +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 +quack +quads +quaff +quags +quail +quair +quais +quake +quaky +quale +qualm +quant +quare +quark +quart +quash +quasi +quass +quate +quats +quayd +quays +qubit +quean +queen +queer +quell +queme +quena +quern +query +quest +queue +queyn +queys +quich +quick +quids +quiet +quiff +quill +quilt +quims +quina +quine +quino +quins +quint +quipo +quips +quipu +quire +quirk +quirt +quist +quite +quits +quoad +quods +quoif +quoin +quoit +quoll +quonk +quops +quota +quote +quoth +qursh +quyte +rabat +rabbi +rabic +rabid +rabis +raced +racer +races +rache +racks +racon +radar +radge +radii +radio +radix +radon +raffs +rafts +ragas +ragde +raged +ragee +rager +rages +ragga +raggs +raggy +ragis +ragus +rahed +rahui +raias +raids +raiks +raile +rails +raine +rains +rainy +raird +raise +raita +raits +rajah +rajas +rajes +raked +rakee +raker +rakes +rakia +rakis +rakus +rales +rally +ralph +ramal +ramee +ramen +ramet +ramie +ramin +ramis +rammy +ramps +ramus +ranas +rance +ranch +rands +randy +ranee +ranga +range +rangi +rangs +rangy +ranid +ranis +ranke +ranks +rants +raped +raper +rapes +raphe +rapid +rappe +rared +raree +rarer +rares +rarks +rased +raser +rases +rasps +raspy +rasse +rasta +ratal +ratan +ratas +ratch +rated +ratel +rater +rates +ratha +rathe +raths +ratio +ratoo +ratos +ratty +ratus +rauns +raupo +raved +ravel +raven +raver +raves +ravey +ravin +rawer +rawin +rawly +rawns +raxed +raxes +rayah +rayas +rayed +rayle +rayne +rayon +razed +razee +razer +razes +razoo +razor +reach +react +readd +reads +ready +reais +reaks +realm +realo +reals +reame +reams +reamy +reans +reaps +rearm +rears +reast +reata +reate +reave +rebar +rebbe +rebec +rebel +rebid +rebit +rebop +rebus +rebut +rebuy +recal +recap +recce +recco +reccy +recit +recks +recon +recta +recti +recto +recur +recut +redan +redds +reddy +reded +redes +redia +redid +redip +redly +redon +redos +redox +redry +redub +redux +redye +reech +reede +reeds +reedy +reefs +reefy +reeks +reeky +reels +reens +reest +reeve +refed +refel +refer +reffo +refis +refit +refix +refly +refry +regal +regar +reges +reggo +regie +regma +regna +regos +regur +rehab +rehem +reifs +reify +reign +reiki +reiks +reink +reins +reird +reist +reive +rejig +rejon +reked +rekes +rekey +relax +relay +relet +relic +relie +relit +rello +reman +remap +remen +remet +remex +remit +remix +renal +renay +rends +renew +reney +renga +renig +renin +renne +renos +rente +rents +reoil +reorg +repay +repeg +repel +repin +repla +reply +repos +repot +repps +repro +reran +rerig +rerun +resat +resaw +resay +resee +reses +reset +resew +resid +resin +resit +resod +resow +resto +rests +resty +resus +retag +retax +retch +retem +retia +retie +retox +retro +retry +reuse +revel +revet +revie +revue +rewan +rewax +rewed +rewet +rewin +rewon +rewth +rexes +rezes +rheas +rheme +rheum +rhies +rhime +rhine +rhino +rhody +rhomb +rhone +rhumb +rhyme +rhyne +rhyta +riads +rials +riant +riata +ribas +ribby +ribes +riced +ricer +rices +ricey +richt +ricin +ricks +rider +rides +ridge +ridgy +ridic +riels +riems +rieve +rifer +riffs +rifle +rifte +rifts +rifty +riggs +right +rigid +rigol +rigor +riled +riles +riley +rille +rills +rimae +rimed +rimer +rimes +rimus +rinds +rindy +rines +rings +rinks +rinse +rioja +riots +riped +ripen +riper +ripes +ripps +risen +riser +rises +rishi +risks +risky +risps +risus +rites +ritts +ritzy +rival +rivas +rived +rivel +riven +river +rives +rivet +riyal +rizas +roach +roads +roams +roans +roars +roary +roast +roate +robed +robes +robin +roble +robot +rocks +rocky +roded +rodeo +rodes +roger +rogue +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 +roomy +roons +roops +roopy +roosa +roose +roost +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 +rotor +rotos +rotte +rouen +roues +rouge +rough +roule +rouls +roums +round +roups +roupy +rouse +roust +route +routh +routs +roved +roven +rover +roves +rowan +rowdy +rowed +rowel +rowen +rower +rowie +rowme +rownd +rowth +rowts +royal +royne +royst +rozet +rozit +ruana +rubai +rubby +rubel +rubes +rubin +ruble +rubli +rubus +ruche +rucks +rudas +rudds +ruddy +ruder +rudes +rudie +rudis +rueda +ruers +ruffe +ruffs +rugae +rugal +rugby +ruggy +ruing +ruins +rukhs +ruled +ruler +rules +rumal +rumba +rumbo +rumen +rumes +rumly +rummy +rumor +rumpo +rumps +rumpy +runch +runds +runed +runes +rungs +runic +runny +runts +runty +rupee +rupia +rural +rurps +rurus +rusas +ruses +rushy +rusks +rusma +russe +rusts +rusty +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 +sadly +sados +sadza +safed +safer +safes +sagas +sager +sages +saggy +sagos +sagum +saheb +sahib +saice +saick +saics +saids +saiga +sails +saims +saine +sains +saint +sairs +saist +saith +sajou +sakai +saker +sakes +sakia +sakis +sakti +salad +salal +salat +salep +sales +salet +salic +salix +salle +sally +salmi +salol +salon +salop +salpa +salps +salsa +salse +salto +salts +salty +salue +salut +salve +salvo +saman +samas +samba +sambo +samek +samel +samen +sames +samey +samfu +sammy +sampi +samps +sands +sandy +saned +saner +sanes +sanga +sangh +sango +sangs +sanko +sansa +santo +sants +saola +sapan +sapid +sapor +sappy +saran +sards +sared +saree +sarge +sargo +sarin +saris +sarks +sarky +sarod +saros +sarus +saser +sasin +sasse +sassy +satai +satay +sated +satem +sates +satin +satis +satyr +sauba +sauce +sauch +saucy +saugh +sauls +sault +sauna +saunt +saury +saute +sauts +saved +saver +saves +savey +savin +savor +savoy +savvy +sawah +sawed +sawer +saxes +sayed +sayer +sayid +sayne +sayon +sayst +sazes +scabs +scads +scaff +scags +scail +scala +scald +scale +scall +scalp +scaly +scamp +scams +scand +scans +scant +scapa +scape +scapi +scare +scarf +scarp +scars +scart +scary +scath +scats +scatt +scaud +scaup +scaur +scaws +sceat +scena +scend +scene +scent +schav +schmo +schul +schwa +scion +sclim +scody +scoff +scogs +scold +scone +scoog +scoop +scoot +scopa +scope +scops +score +scorn +scots +scoug +scoup +scour +scout +scowl +scowp +scows +scrab +scrae +scrag +scram +scran +scrap +scrat +scraw +scray +scree +screw +scrim +scrip +scrob +scrod +scrog +scrow +scrub +scrum +scuba +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 +sedan +seder +sedes +sedge +sedgy +sedum +seeds +seedy +seeks +seeld +seels +seely +seems +seeps +seepy +seers +sefer +segar +segni +segno +segol +segos +segue +sehri +seifs +seils +seine +seirs +seise +seism +seity +seiza +seize +sekos +sekts +selah +seles +selfs +sella +selle +sells +selva +semee +semen +semes +semie +semis +senas +sends +senes +sengi +senna +senor +sensa +sense +sensi +sente +senti +sents +senvy +senza +sepad +sepal +sepia +sepic +sepoy +septa +septs +serac +serai +seral +sered +serer +seres +serfs +serge +seric +serif +serin +serks +seron +serow +serra +serre +serrs +serry +serum +serve +servo +sesey +sessa +setae +setal +seton +setts +setup +seven +sever +sewan +sewar +sewed +sewel +sewen +sewer +sewin +sexed +sexer +sexes +sexto +sexts +seyen +shack +shade +shads +shady +shaft +shags +shahs +shake +shako +shakt +shaky +shale +shall +shalm +shalt +shaly +shama +shame +shams +shand +shank +shans +shape +shaps +shard +share +shark +sharn +sharp +shash +shaul +shave +shawl +shawm +shawn +shaws +shaya +shays +shchi +sheaf +sheal +shear +sheas +sheds +sheel +sheen +sheep +sheer +sheet +sheik +shelf +shell +shend +shent +sheol +sherd +shere +shero +shets +sheva +shewn +shews +shiai +shied +shiel +shier +shies +shift +shill +shily +shims +shine +shins +shiny +ships +shire +shirk +shirr +shirs +shirt +shish +shiso +shist +shite +shits +shiur +shiva +shive +shivs +shlep +shlub +shmek +shmoe +shoal +shoat +shock +shoed +shoer +shoes +shogi +shogs +shoji +shojo +shola +shone +shook +shool +shoon +shoos +shoot +shope +shops +shore +shorl +shorn +short +shote +shots +shott +shout +shove +showd +shown +shows +showy +shoyu +shred +shrew +shris +shrow +shrub +shrug +shtik +shtum +shtup +shuck +shule +shuln +shuls +shuns +shunt +shura +shush +shute +shuts +shwas +shyer +shyly +sials +sibbs +sibyl +sices +sicht +sicko +sicks +sicky +sidas +sided +sider +sides +sidha +sidhe +sidle +siege +sield +siens +sient +sieth +sieur +sieve +sifts +sighs +sight +sigil +sigla +sigma +signa +signs +sijos +sikas +siker +sikes +silds +siled +silen +siler +siles +silex +silks +silky +sills +silly +silos +silts +silty +silva +simar +simas +simba +simis +simps +simul +since +sinds +sined +sines +sinew +singe +sings +sinhs +sinks +sinky +sinus +siped +sipes +sippy +sired +siree +siren +sires +sirih +siris +siroc +sirra +sirup +sisal +sises +sissy +sista +sists +sitar +sited +sites +sithe +sitka +situp +situs +siver +sixer +sixes +sixmo +sixte +sixth +sixty +sizar +sized +sizel +sizer +sizes +skags +skail +skald +skank +skart +skate +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 +skier +skies +skiey +skiff +skill +skimo +skimp +skims +skink +skins +skint +skios +skips +skirl +skirr +skirt +skite +skits +skive +skivy +sklim +skoal +skody +skoff +skogs +skols +skool +skort +skosh +skran +skrik +skuas +skugs +skulk +skull +skunk +skyed +skyer +skyey +skyfs +skyre +skyrs +skyte +slabs +slack +slade +slaes +slags +slaid +slain +slake +slams +slane +slang +slank +slant +slaps +slart +slash +slate +slats +slaty +slave +slaws +slays +slebs +sleds +sleek +sleep +sleer +sleet +slept +slews +sleys +slice +slick +slide +slier +slily +slime +slims +slimy +sling +slink +slipe +slips +slipt +slish +slits +slive +sloan +slobs +sloes +slogs +sloid +slojd +slomo +sloom +sloop +sloot +slope +slops +slopy +slorm +slosh +sloth +slots +slove +slows +sloyd +slubb +slubs +slued +slues +sluff +slugs +sluit +slump +slums +slung +slunk +slurb +slurp +slurs +sluse +slush +sluts +slyer +slyly +slype +smaak +smack +smaik +small +smalm +smalt +smarm +smart +smash +smaze +smear +smeek +smees +smeik +smeke +smell +smelt +smerk +smews +smile +smirk +smirr +smirs +smite +smith +smits +smock +smogs +smoke +smoko +smoky +smolt +smoor +smoot +smore +smorg +smote +smout +smowt +smugs +smurs +smush +smuts +snabs +snack +snafu +snags +snail +snake +snaky +snaps +snare +snarf +snark +snarl +snars +snary +snash +snath +snaws +snead +sneak +sneap +snebs +sneck +sneds +sneed +sneer +snees +snell +snibs +snick +snide +snies +sniff +snift +snigs +snipe +snips +snipy +snirt +snits +snobs +snods +snoek +snoep +snogs +snoke +snood +snook +snool +snoop +snoot +snore +snort +snots +snout +snowk +snows +snowy +snubs +snuck +snuff +snugs +snush +snyes +soaks +soaps +soapy +soare +soars +soave +sobas +sober +socas +soces +socko +socks +socle +sodas +soddy +sodic +sodom +sofar +sofas +softa +softs +softy +soger +soggy +sohur +soils +soily +sojas +sojus +sokah +soken +sokes +sokol +solah +solan +solar +solas +solde +soldi +soldo +solds +soled +solei +soler +soles +solid +solon +solos +solum +solus +solve +soman +somas +sonar +sonce +sonde +sones +songs +sonic +sonly +sonne +sonny +sonse +sonsy +sooey +sooks +sooky +soole +sools +sooms +soops +soote +sooth +soots +sooty +sophs +sophy +sopor +soppy +sopra +soral +soras +sorbo +sorbs +sorda +sordo +sords +sored +soree +sorel +sorer +sores +sorex +sorgo +sorns +sorra +sorry +sorta +sorts +sorus +soths +sotol +souce +souct +sough +souks +souls +soums +sound +soups +soupy +sours +souse +south +souts +sowar +sowce +sowed +sower +sowff +sowfs +sowle +sowls +sowms +sownd +sowne +sowps +sowse +sowth +soyas +soyle +soyuz +sozin +space +spacy +spade +spado +spaed +spaer +spaes +spags +spahi +spail +spain +spait +spake +spald +spale +spall +spalt +spams +spane +spang +spank +spans +spard +spare +spark +spars +spart +spasm +spate +spats +spaul +spawl +spawn +spaws +spayd +spays +spaza +spazz +speak +speal +spean +spear +speat +speck +specs +spect +speed +speel +speer +speil +speir +speks +speld +spelk +spell +spelt +spend +spent +speos +sperm +spets +speug +spews +spewy +spial +spica +spice +spick +spics +spicy +spide +spied +spiel +spier +spies +spiff +spifs +spike +spiks +spiky +spile +spill +spilt +spims +spina +spine +spink +spins +spiny +spire +spirt +spiry +spite +spits +spitz +spivs +splat +splay +split +splog +spode +spods +spoil +spoke +spoof +spook +spool +spoom +spoon +spoor +spoot +spore +spork +sport +sposh +spots +spout +sprad +sprag +sprat +spray +spred +spree +sprew +sprig +sprit +sprod +sprog +sprue +sprug +spuds +spued +spuer +spues +spugs +spule +spume +spumy +spunk +spurn +spurs +spurt +sputa +spyal +spyre +squab +squad +squat +squaw +squeg +squib +squid +squit +squiz +stabs +stack +stade +staff +stage +stags +stagy +staid +staig +stain +stair +stake +stale +stalk +stall +stamp +stand +stane +stang +stank +staph +staps +stare +stark +starn +starr +stars +start +stash +state +stats +staun +stave +staws +stays +stead +steak +steal +steam +stean +stear +stedd +stede +steds +steed +steek +steel +steem +steen +steep +steer +steil +stein +stela +stele +stell +steme +stems +stend +steno +stens +stent +steps +stept +stere +stern +stets +stews +stewy +steys +stich +stick +stied +sties +stiff +stilb +stile +still +stilt +stime +stims +stimy +sting +stink +stint +stipa +stipe +stire +stirk +stirp +stirs +stive +stivy +stoae +stoai +stoas +stoat +stobs +stock +stoep +stogy +stoic +stoit +stoke +stole +stoln +stoma +stomp +stond +stone +stong +stonk +stonn +stony +stood +stook +stool +stoop +stoor +stope +stops +stopt +store +stork +storm +story +stoss +stots +stott +stoun +stoup +stour +stout +stove +stown +stowp +stows +strad +strae +strag +strak +strap +straw +stray +strep +strew +stria +strig +strim +strip +strop +strow +stroy +strum +strut +stubs +stuck +stude +studs +study +stuff +stull +stulm +stumm +stump +stums +stung +stunk +stuns +stunt +stupa +stupe +sture +sturt +styed +styes +style +styli +stylo +styme +stymy +styre +styte +suave +subah +subas +subby +suber +subha +succi +sucks +sucky +sucre +sudds +sudor +sudsy +suede +suent +suers +suete +suets +suety +sugan +sugar +sughs +sugos +suhur +suids +suing +suint +suite +suits +sujee +sukhs +sukuk +sulci +sulfa +sulfo +sulks +sulky +sully +sulph +sulus +sumac +sumis +summa +sumos +sumph +sumps +sunis +sunks +sunna +sunns +sunny +sunup +super +supes +supra +surah +sural +suras +surat +surds +sured +surer +sures +surfs +surfy +surge +surgy +surly +surra +sused +suses +sushi +susus +sutor +sutra +sutta +swabs +swack +swads +swage +swags +swail +swain +swale +swaly +swami +swamp +swamy +swang +swank +swans +swaps +swapt +sward +sware +swarf +swarm +swart +swash +swath +swats +swayl +sways +sweal +swear +sweat +swede +sweed +sweel +sweep +sweer +swees +sweet +sweir +swell +swelt +swept +swerf +sweys +swies +swift +swigs +swile +swill +swims +swine +swing +swink +swipe +swire +swirl +swish +swiss +swith +swits +swive +swizz +swobs +swole +swoln +swoon +swoop +swops +swopt +sword +swore +sworn +swots +swoun +swung +sybbe +sybil +syboe +sybow +sycee +syces +sycon +syens +syker +sykes +sylis +sylph +sylva +symar +synch +syncs +synds +syned +synes +synod +synth +syped +sypes +syphs +syrah +syren +syrup +sysop +sythe +syver +taals +taata +tabby +taber +tabes +tabid +tabis +tabla +table +taboo +tabor +tabun +tabus +tacan +taces +tacet +tache +tacho +tachs +tacit +tacks +tacky +tacos +tacts +taels +taffy +tafia +taggy +tagma +tahas +tahrs +taiga +taigs +taiko +tails +tains +taint +taira +taish +taits +tajes +takas +taken +taker +takes +takhi +takin +takis +takky +talak +talaq +talar +talas +talcs +talcy +talea +taler +tales +talks +talky +talls +tally +talma +talon +talpa +taluk +talus +tamal +tamed +tamer +tames +tamin +tamis +tammy +tamps +tanas +tanga +tangi +tango +tangs +tangy +tanhs +tanka +tanks +tanky +tanna +tansy +tanti +tanto +tanty +tapas +taped +tapen +taper +tapes +tapet +tapir +tapis +tappa +tapus +taras +tardo +tardy +tared +tares +targa +targe +tarns +taroc +tarok +taros +tarot +tarps +tarre +tarry +tarsi +tarts +tarty +tasar +tased +taser +tases +tasks +tassa +tasse +tasso +taste +tasty +tatar +tater +tates +taths +tatie +tatou +tatts +tatty +tatus +taube +tauld +taunt +tauon +taupe +tauts +tavah +tavas +taver +tawai +tawas +tawed +tawer +tawie +tawny +tawse +tawts +taxed +taxer +taxes +taxis +taxol +taxon +taxor +taxus +tayra +tazza +tazze +teach +teade +teads +teaed +teaks +teals +teams +tears +teary +tease +teats +teaze +techs +techy +tecta +teddy +teels +teems +teend +teene +teens +teeny +teers +teeth +teffs +teggs +tegua +tegus +tehrs +teiid +teils +teind +teins +telae +telco +teles +telex +telia +telic +tells +telly +teloi +telos +temed +temes +tempi +tempo +temps +tempt +temse +tench +tends +tendu +tenes +tenet +tenge +tenia +tenne +tenno +tenny +tenon +tenor +tense +tenth +tents +tenty +tenue +tepal +tepas +tepee +tepid +tepoy +terai +teras +terce +terek +teres +terfe +terfs +terga +terms +terne +terns +terra +terry +terse +terts +tesla +testa +teste +tests +testy +tetes +teths +tetra +tetri +teuch +teugh +tewed +tewel +tewit +texas +texes +texts +thack +thagi +thaim +thale +thali +thana +thane +thang +thank +thans +thanx +tharm +thars +thaws +thawy +thebe +theca +theed +theek +thees +theft +thegn +theic +thein +their +thelf +thema +theme +thens +theow +there +therm +these +thesp +theta +thete +thews +thewy +thick +thief +thigh +thigs +thilk +thill +thine +thing +think +thins +thiol +third +thirl +thoft +thole +tholi +thong +thorn +thoro +thorp +those +thous +thowl +thrae +thraw +three +threw +thrid +thrip +throb +throe +throw +thrum +thuds +thugs +thuja +thumb +thump +thunk +thurl +thuya +thyme +thymi +thymy +tians +tiara +tiars +tibia +tical +ticca +ticed +tices +tichy +ticks +ticky +tidal +tiddy +tided +tides +tiers +tiffs +tifos +tifts +tiger +tiges +tight +tigon +tikas +tikes +tikis +tikka +tilak +tilde +tiled +tiler +tiles +tills +tilly +tilth +tilts +timbo +timed +timer +times +timid +timon +timps +tinas +tinct +tinds +tinea +tined +tines +tinge +tings +tinks +tinny +tints +tinty +tipis +tippy +tipsy +tired +tires +tirls +tiros +tirrs +titan +titch +titer +tithe +titis +title +titre +titty +titup +tiyin +tiyns +tizes +tizzy +toads +toady +toast +toaze +tocks +tocky +tocos +today +todde +toddy +toeas +toffs +toffy +tofts +tofus +togae +togas +toged +toges +togue +tohos +toile +toils +toing +toise +toits +tokay +toked +token +toker +tokes +tokos +tolan +tolar +tolas +toled +toles +tolls +tolly +tolts +tolus +tolyl +toman +tombs +tomes +tomia +tommy +tomos +tonal +tondi +tondo +toned +toner +tones +toney +tonga +tongs +tonic +tonka +tonks +tonne +tonus +tools +tooms +toons +tooth +toots +topaz +toped +topee +topek +toper +topes +tophe +tophi +tophs +topic +topis +topoi +topos +toppy +toque +torah +toran +toras +torch +torcs +tores +toric +torii +toros +torot +torrs +torse +torsi +torsk +torso +torta +torte +torts +torus +tosas +tosed +toses +toshy +tossy +total +toted +totem +toter +totes +totty +touch +tough +touks +touns +tours +touse +tousy +touts +touze +touzy +towed +towel +tower +towie +towns +towny +towse +towsy +towts +towze +towzy +toxic +toxin +toyed +toyer +toyon +toyos +tozed +tozes +tozie +trabs +trace +track +tract +trade +trads +tragi +traik +trail +train +trait +tramp +trams +trank +tranq +trans +trant +trape +traps +trapt +trash +trass +trats +tratt +trave +trawl +trayf +trays +tread +treat +treck +treed +treen +trees +trefa +treif +treks +trema +trems +trend +tress +trest +trets +trews +treyf +treys +triac +triad +trial +tribe +trice +trick +tride +tried +trier +tries +triff +trigo +trigs +trike +trild +trill +trims +trine +trins +triol +trior +trios +tripe +trips +tripy +trist +trite +troad +troak +troat +trock +trode +trods +trogs +trois +troke +troll +tromp +trona +tronc +trone +tronk +trons +troop +trooz +trope +troth +trots +trout +trove +trows +troys +truce +truck +trued +truer +trues +trugo +trugs +trull +truly +trump +trunk +truss +trust +truth +tryer +tryke +tryma +tryps +tryst +tsade +tsadi +tsars +tsked +tsuba +tsubo +tuans +tuart +tuath +tubae +tubal +tubar +tubas +tubby +tubed +tuber +tubes +tucks +tufas +tuffe +tuffs +tufts +tufty +tugra +tuile +tuina +tuism +tuktu +tules +tulip +tulle +tulpa +tulsi +tumid +tummy +tumor +tumps +tumpy +tunas +tunds +tuned +tuner +tunes +tungs +tunic +tunny +tupek +tupik +tuple +tuque +turbo +turds +turfs +turfy +turks +turme +turms +turns +turnt +turps +turrs +tushy +tusks +tusky +tutee +tutor +tutti +tutty +tutus +tuxes +tuyer +twaes +twain +twals +twang +twank +twats +tways +tweak +tweed +tweel +tween +tweep +tweer +tweet +twerk +twerp +twice +twier +twigs +twill +twilt +twine +twink +twins +twiny +twire +twirl +twirp +twist +twite +twits +twixt +twoer +twyer +tyees +tyers +tying +tyiyn +tykes +tyler +tymps +tynde +tyned +tynes +typal +typed +types +typey +typic +typos +typps +typto +tyran +tyred +tyres +tyros +tythe +tzars +udals +udder +udons +ugali +ugged +uhlan +uhuru +ukase +ulama +ulans +ulcer +ulema +ulmin +ulnad +ulnae +ulnar +ulnas +ulpan +ultra +ulvas +ulyie +ulzie +umami +umbel +umber +umble +umbos +umbra +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 +uncle +uncos +uncoy +uncus +uncut +undam +undee +under +undid +undos +undue +undug +uneth +unfed +unfit +unfix +ungag +unget +ungod +ungot +ungum +unhat +unhip +unica +unify +union +unite +units +unity +unjam +unked +unket +unkid +unlaw +unlay +unled +unlet +unlid +unlit +unman +unmet +unmew +unmix +unpay +unpeg +unpen +unpin +unred +unrid +unrig +unrip +unsaw +unsay +unsee +unset +unsew +unsex +unsod +untax +untie +until +untin +unwed +unwet +unwit +unwon +unzip +upbow +upbye +updos +updry +upend +upjet +uplay +upled +uplit +upped +upper +upran +uprun +upsee +upset +upsey +uptak +upter +uptie +uraei +urali +uraos +urare +urari +urase +urate +urban +urbex +urbia +urdee +ureal +ureas +uredo +ureic +urena +urent +urged +urger +urges +urial +urine +urite +urman +urnal +urned +urped +ursae +ursid +urson +urubu +urvas +usage +users +usher +using +usnea +usque +usual +usure +usurp +usury +uteri +utile +utter +uveal +uveas +uvula +vacua +vaded +vades +vagal +vague +vagus +vails +vaire +vairs +vairy +vakas +vakil +vales +valet +valid +valis +valor +valse +value +valve +vamps +vampy +vanda +vaned +vanes +vangs +vants +vaped +vaper +vapes +vapid +vapor +varan +varas +vardy +varec +vares +varia +varix +varna +varus +varve +vasal +vases +vasts +vasty +vatic +vatus +vauch +vault +vaunt +vaute +vauts +vawte +vaxes +veale +veals +vealy +veena +veeps +veers +veery +vegan +vegas +veges +vegie +vegos +vehme +veils +veily +veins +veiny +velar +velds +veldt +veles +vells +velum +venae +venal +vends +vendu +veney +venge +venin +venom +vents +venue +venus +verbs +verge +verra +verry +verse +verso +verst +verts +vertu +verve +vespa +vesta +vests +vetch +vexed +vexer +vexes +vexil +vezir +vials +viand +vibes +vibex +vibey +vicar +viced +vices +vichy +video +viers +views +viewy +vifda +viffs +vigas +vigia +vigil +vigor +vilde +viler +villa +villi +vills +vimen +vinal +vinas +vinca +vined +viner +vines +vinew +vinic +vinos +vints +vinyl +viola +viold +viols +viper +viral +vired +vireo +vires +virga +virge +virid +virls +virtu +virus +visas +vised +vises +visie +visit +visne +vison +visor +vista +visto +vitae +vital +vitas +vitex +vitro +vitta +vivas +vivat +vivda +viver +vives +vivid +vixen +vizir +vizor +vleis +vlies +vlogs +voars +vocab +vocal +voces +voddy +vodka +vodou +vodun +voema +vogie +vogue +voice +voids +voila +voile +voips +volae +volar +voled +voles +volet +volks +volta +volte +volti +volts +volva +volve +vomer +vomit +voted +voter +votes +vouch +vouge +voulu +vowed +vowel +vower +voxel +vozhd +vraic +vrils +vroom +vrous +vrouw +vrows +vuggs +vuggy +vughs +vughy +vulgo +vulns +vulva +vutty +vying +waacs +wacke +wacko +wacks +wacky +wadds +waddy +waded +wader +wades +wadge +wadis +wadts +wafer +waffs +wafts +waged +wager +wages +wagga +wagon +wagyu +wahoo +waide +waifs +waift +wails +wains +wairs +waist +waite +waits +waive +wakas +waked +waken +waker +wakes +wakfs +waldo +walds +waled +waler +wales +walie +walis +walks +walla +walls +wally +walty +waltz +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 +warty +wases +washy +wasms +wasps +waspy +waste +wasts +watap +watch +water +watts +wauff +waugh +wauks +waulk +wauls +waurs +waved +waver +waves +wavey +wawas +wawes +wawls +waxed +waxen +waxer +waxes +wayed +wazir +wazoo +weald +weals +weamb +weans +wears +weary +weave +webby +weber +wecht +wedel +wedge +wedgy +weeds +weedy +weeke +weeks +weels +weems +weens +weeny +weeps +weepy +weest +weete +weets +wefte +wefts +weids +weigh +weils +weird +weirs +weise +weize +wekas +welch +welds +welke +welks +welkt +wells +welly +welsh +welts +wembs +wench +wends +wenge +wenny +wents +weros +wersh +wests +wetas +wetly +wexed +wexes +whack +whale +whamo +whams +whang +whaps +whare +wharf +whata +whats +whaup +whaur +wheal +whear +wheat +wheel +wheen +wheep +wheft +whelk +whelm +whelp +whens +where +whets +whews +wheys +which +whids +whiff +whift +whigs +while +whilk +whims +whine +whins +whiny +whios +whips +whipt +whirl +whirr +whirs +whish +whisk +whiss +whist +white +whits +whity +whizz +whole +whomp +whoof +whoop +whoot +whops +whore +whorl +whort +whose +whoso +whows +whump +whups +whyda +wicca +wicks +wicky +widdy +widen +wider +wides +widow +width +wield +wiels +wifed +wifes +wifey +wifie +wifty +wigan +wigga +wiggy +wight +wikis +wilco +wilds +wiled +wiles +wilga +wilis +wilja +wills +willy +wilts +wimps +wimpy +wince +winch +winds +windy +wined +wines +winey +winge +wings +wingy +winks +winna +winns +winos +winze +wiped +wiper +wipes +wired +wirer +wires +wirra +wised +wiser +wises +wisha +wisht +wisps +wispy +wists +witan +witch +wited +wites +withe +withs +withy +witty +wived +wiver +wives +wizen +wizes +woads +woald +wocks +wodge +woful +wojus +woken +woker +wokka +wolds +wolfs +wolly +wolve +woman +wombs +womby +women +womyn +wonga +wongi +wonks +wonky +wonts +woods +woody +wooed +wooer +woofs +woofy +woold +wools +wooly +woons +woops +woopy +woose +woosh +wootz +woozy +words +wordy +works +world +worms +wormy +worry +worse +worst +worth +worts +would +wound +woven +wowed +wowee +woxen +wrack +wrang +wraps +wrapt +wrast +wrate +wrath +wrawl +wreak +wreck +wrens +wrest +wrick +wried +wrier +wries +wring +wrist +write +writs +wroke +wrong +wroot +wrote +wroth +wrung +wryer +wryly +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 +yacht +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 +yearn +years +yeast +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 +yield +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 +young +yourn +yours +yourt +youse +youth +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 +zebra +zebub +zebus +zedas +zeins +zendo +zerda +zerks +zeros +zests +zesty +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 +zonal +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 diff --git a/examples/wordle/wordle_hash.txt b/examples/wordle/wordle_hash.txt new file mode 100644 index 0000000..f17cffe --- /dev/null +++ b/examples/wordle/wordle_hash.txt @@ -0,0 +1,611 @@ +2315 @ b5d615cc5e0be1745e3fcf40e8e20e8d: soare +2 @ 41ad8e7b17f8e869ce74ad6d7bce9b6a: azure +8 @ ac3a4b44e1a5a406d221705a94771232: bundt +14 @ e4e9d5772d545f64d8b69fe91cdb42e6: chals +2 @ a5c25ae0f0fd0fa4a23c1cfbe74800a7: flask +27 @ 09c7394553fd7e485f551ad9010b86f9: maron +4 @ 7398ad11f7afd69666453a350dabab11: marsh +3 @ 808dd0740178dff9520e5f45318c76f6: mason +40 @ 4ba92201322ea884ab4a6c79ca1f12e8: gault +5 @ 8802749fdcfd7f10b02db11d3a29832c: ajwan +40 @ 9f1362121383354cd0e4a68cd931e518: clink +3 @ 9e39cf7b4bc209308902a0d9916aaff8: aahed +44 @ 8cf0a21708ffc7cc8cb0d8fa53cc8759: cloot +28 @ 3cb2ec3fe1dfeb4cfafc349780240541: glitz +2 @ 89d4250f107f76112d50fe11c717ced7: viola +2 @ 168528b4bda9ca4a4207e0aa33d68941: adopt +3 @ 476de9f64648c212562420b238501825: among +4 @ 96d795ff32d9755ed4b5bb3b7e9567e6: mango +4 @ e78efa403c6b09d91a30b33d03b4fa9d: abaft +2 @ e2e1fa1534ab82993928f24e83fcd998: havoc +7 @ b3e78323f28f9da8d4329d8b78736d6f: belch +2 @ 8991252f9b7e997dd4ec905aef33ea5e: aloud +2 @ c2a4f935486f7d6e0820f2f71298bd47: mange +6 @ 2771ae0089b54536e24d710f51ac3941: abaca +7 @ 41d3a9e28afb76b85dbf65f8556ffd2b: barca +15 @ f203b42eef3862c5f3dc3fc2b43fe7f4: thump +57 @ 5307436efcbe7f644e1ba31f2652a8fa: glint +2 @ 7380baf5ab7fc260342c10979bbc6bb7: druid +3 @ 4671ccfea7c3ad65c2e35e3b4d80c595: false +3 @ 564dca50e3cb686c3d98aca8522bd809: mirth +61 @ 21c785d22f8a7f54748845d92bba6648: talar +2 @ f7063df8f00236864f513b47373dceb5: cause +3 @ d81189c5027438a52e57b9c80b1e4863: abaci +2 @ a1955b756b05714af031e5643ee705f5: angle +7 @ 02a52d7dc85bc968796662b49c937084: agloo +4 @ 5104261d903434a2511c8a6f0c8bede5: ample +68 @ 75a088c23f3072ba0831b3d047af0cbc: canal +4 @ 95e1011e7f90eb2f03128122e6c3180e: theta +8 @ ca0d1790b4735740d493cc95a8170775: weave +23 @ 491d5b96345a4bbfba06ee8b0b52b3fd: linty +79 @ b29725c0cce7ea264f2133c4c8cf4efb: guilt +11 @ 7a39f8099ad27003079961316a3e8a3e: humic +2 @ 072ac9a403b7c8b121f18b2fe47755dc: usual +2 @ b3700c279e0680a761e8d6798434392e: cycle +2 @ 06f3d9711c8e72193ce6277326844ff1: parry +2 @ 59b8545d0870daae905ed3cb87cc29b5: anime +3 @ bf28c472047b6f63630a999ce98f667c: basis +2 @ 90f15a733bfd92260e1b7e6a67f69109: gassy +3 @ a82ecc90d5288b57315e1dd0312afad9: abaca +5 @ 0150e8e8524c47253886b6ff6e994a87: wagon +13 @ 7bbd201263334d87bcdaa5ce868e4302: dhuti +4 @ 53c189e3605d06042abeba34cd95828a: abaft +3 @ d86ddeb2bd9f62b0e9da7bf3b90bce5f: aargh +2 @ 0ae90df6adda7d58a3f757af526c09a0: agape +4 @ 0147362180f027b41f426355903134d8: enema +117 @ f404120cbcc00bd07d4f86735018c41a: direr +6 @ 19c90a57b11c9c037c5c0b3e088bbca5: bated +120 @ f13f1004c8da1e5494dda1d7643275d7: denet +4 @ 98ba6ab65a1936a5035a71d7c7b85dbf: arbor +4 @ 324622020b26e6a94e6d93d6caf01c3f: bevel +4 @ 7c8baafc71e2b722c302cd9f43760b7e: fella +42 @ 9147697d44692f38e611fbd4a0db4c8c: riyal +5 @ 93da81b18885b587bcef276245156ffa: pixel +11 @ 0e22906c347ec37232514187909629e1: belch +3 @ f4b62c45c254a28144ef2feb189a1010: tapir +5 @ 725c1409b91d0576fce9332a0ea97f35: wheat +3 @ aae1d882950ac4445d854783c05ab35f: vegan +2 @ 198625e8e7c488c3f71110838ca0e68e: guava +21 @ 068b89775a8892c8517fe7d243115c41: butyl +138 @ ac7c43d21ea81880fecda60ac78015a9: clint +4 @ 62256b729b6290b172c34f6fe1224f28: wheat +2 @ 62065515ad55a0004ff00207722717ff: alive +2 @ bd762dc587d3a152607244b36a9b6dd2: faith +3 @ d116213bfcf06cea92aa90ef6d6ceb4b: inlay +3 @ 0655528c57366488423aeef61a2958cc: alpha +5 @ f58c6feca0f89a3f03cda348ad4d1fe6: tally +2 @ 8bc70e966bfe52def1dc1a3c2a5cc43f: allay +15 @ 8f8818673e661017c68328c4ae9052c2: fubsy +6 @ 3ed1cf9c0535128a027c65df7da07a02: neigh +3 @ 89bccf8e919de1c52f69197edac7f943: raise +2 @ ce6f959277e78d6432b80b059afeb3b0: alley +2 @ 3e4d97eca34d1f480b72eaa0070e65ad: alloy +8 @ c0749f36eb581fae543a7b9eef8c2387: balmy +3 @ 7079a71d1b0a88d7a3b99ff46a56ea14: audit +7 @ f928277133b7398d3baf4731cbace2f2: belch +3 @ e94a82ef46323e7813baa3cf25b0aaf0: drink +12 @ dd1ede8d9d19c77eb7038e0559bb87a6: dampy +4 @ f59f1381b44546dcd4d0a5c3fd3a329f: parka +6 @ 927b844f9bd0ee7584aae8a93a80293d: maxim +2 @ 8cbc83f4db19b165241fdf7d6f99d30f: burnt +3 @ 1509c38015cd5ee4884a0c01f0b05096: tangy +2 @ d74afe4f76bee15502bb46d0866158ca: aping +11 @ 4890b9fb793f2b592e3c6c8e5376d5dd: becke +2 @ 71a50dfd729ae3a3472c35a199bbb0b0: quail +2 @ 60cc10cf0ae13106b891e6b4c7c76d81: apnea +4 @ ae87f652eb88811e30bb65215dfcfa14: befog +5 @ 20fd4da94c07257f84d307863b742abf: altar +3 @ de5d8b76805357a6bd7e09be34adabf3: friar +2 @ dce0bea37f58fe77d0335fe649c8a902: caddy +16 @ 6bf182bf954dea5f678367c3aa99a4a8: cruft +2 @ 4319c0b2bb80cf535e853784cc47a9cc: cagey +2 @ 45759d847f481b951763b2d74f04d277: prism +87 @ 4409ebaef66b8d9bc1cdbce331106ab4: culty +2 @ 746f6b32e7d3e0e8f8a620c53553ce17: croak +4 @ 48370cf6a5869cb7dff16f6a51dd7e71: omega +3 @ d990c40d49fba73ae49831aff6b2b338: going +40 @ a4a85f831c7118ff16fea42552da5e22: clint +3 @ 766e6196473ef10a4521a7bc31027d31: aband +183 @ f2348c704c1c92d5550be1a4a52905e2: clint +3 @ aca45156aa7ef9d1d97dfedf4062e568: blink +15 @ 4abd8fb25e4a622876e300f66b939b67: goody +15 @ 8e829a0250b8610f217dff97cd6a79c0: pigmy +2 @ 0b2f6f0044386c7b0a8b20ee1802b866: lunar +3 @ c363856a2a20bbe43a10cca1db7caed4: woozy +2 @ 39e25dfb5cf68f9331d3f6a6d85984f2: urban +2 @ f763898933300fd618e9ff5398248818: catty +2 @ dd3efbdbbacfce133c39033afca2eb1a: tarot +5 @ fc4ef9b807f8b1e72f108cca60be449b: baghs +4 @ 8311f8203f3072d161bcc1abf1f3de82: tooth +2 @ fd2edacd2356a22c18da028ae319de36: champ +4 @ e5482987d4d3977dbab7650888491f54: beech +2 @ c689aba579cd3f5f28f4438f850301e6: caulk +2 @ b4657be821479bce0df6c30568af47cc: wharf +19 @ 58e6b1d8a38af5aa96e76b05e211ec75: diact +2 @ 754df4eaa39d4869bfbdcba5b4dfbb3b: cheat +3 @ 53457884499e216b22ef9401188c9117: rebar +39 @ 7f484bb6ebbda82a9e729243d2696140: pudic +10 @ 82d5fe2086ad3c60fbdcf14491400a53: cloud +6 @ d13fdf5b1f252575051c8e4d9157cdb1: abamp +5 @ d78ffc7abfdaeaefbfe4642ff9c844b4: whelp +15 @ f004c99a54d57060ddff578ee71b4abe: midgy +2 @ e98cc0d13fe2477ce22758be25cb2b34: brave +2 @ 68a89dd2ee96537645c85ff031701a77: revue +7 @ addb65561d32bd276043adf403f01033: tribe +5 @ b6733dcf17a5b01e4485888bb0c4d589: arrow +5 @ d293f42d68b054373ca283da2006573e: bifid +3 @ c702a45830531cc07f7a94b099f7b6e7: ninja +9 @ 76cef4341d42e57972650e202b16cbfd: faugh +2 @ c4463ed218079318f415721cd320cfe8: paler +56 @ 118f2c6618cd9171f0edd4d195991252: clint +10 @ 93be8d9e3b733cfd5dbdd2781b224977: pixel +5 @ 48bcb6ae2b1bf9438a2da07bb85386d6: crimp +33 @ fa8cc4036b9227408ecfe9cb82e4215d: hists +3 @ c28b6a1199420cd906e54f6f7cf0a309: vault +4 @ 3172590896eaca2a144e17616493b86d: chime +4 @ db3091ecf86bd691608b3e722c6dc490: jumbo +2 @ bdf47f3d1a7c9665113ddd653ffb53ef: flock +5 @ c406a266faba051f109bc1a26a5c9368: manly +7 @ dfd8a4e7132d973ec54bbdfc6184f04e: bachs +3 @ 6d7c747c205396f00ec96044a72a9112: drive +5 @ 3bc675fdf25ef46c4eb6bce4687d82ee: newer +2 @ 582654b7dc8d71a456662a9686cb8444: grief +3 @ 80b96aa1645376ac8daf7353ca6302c6: aduki +2 @ 766a16cd52610bf3077a87aff3c96f19: drawl +2 @ 8e071275bdb85cef14c65734a8b6b95e: vicar +4 @ 64cb0ff13d045de80ab8c057e8c8cd9b: becap +2 @ df9da2110e8789de4f6b6f6121a6fa87: wring +25 @ 7d8a27330cb930215020b66d54352662: lento +3 @ e459218b2a18232eb5fdfcecbc48865e: abamp +3 @ c59f41c4a6f1fb868b4dc34d4da90456: cynic +15 @ 9f85b4385ed3618be1e23952a734d58f: pudgy +2 @ 71929659abffc83cf7ae66525d9a4fd5: muddy +2 @ 43fc5c64aa95b69db5628965c22cd62a: cubic +3 @ 37ae1464373c145dc8071b3d1b07bcd1: wench +3 @ e527158e71d83e0ac478c916eda949ea: abaca +2 @ 4903ee985ca677ea845af875e1e01f6e: hello +5 @ fa2171f957c1564977837867f4ebd420: evict +7 @ 9a824d9caddf18f5eab66eb2ab840bff: theft +7 @ 3720fb22eeadba4923b3b72f28ffe434: amnic +59 @ c2a21a52b965565af351b700bd4fb75b: cutin +3 @ 57b6948e59de6ea0f71a542f7474bdc4: egret +2 @ c8a5e61be5b1424c6d264ebee6011820: clink +2 @ 91d027224e2652ff161b145a16af3067: quake +6 @ 092a2e4fafb24131f9576a4aa4f6b8d3: hamba +5 @ 4cfa362b0b2ed7e3506264df210ef78c: aband +2 @ 2661122ebd490fd4889ecf9da7c6d0f9: cloud +3 @ 3f51c93c264cda6d6c6c23408e3658c2: patty +13 @ 9c3f9fdfff941cd8854d9c3efca56db1: fitch +3 @ f5bd503400e832935b0537bcafbcb06a: gaily +3 @ df9578849266838bda125ab68b3d8988: anvil +5 @ 24c656f42ca7105b35caad678b037c54: apian +3 @ 3b39c287c65689a286be95061d7a4151: guild +20 @ 4f19b5f92f4061d1f8e1ff261a4b6c8d: bling +3 @ a6f9c1f813ad5bd4c097203f22dafffd: abysm +3 @ 3811309f72e7adfb0ba45617eeeefc78: badge +19 @ 78324d64051cba0bf91e6c48e1e52894: uneth +2 @ 95933ed70764583dbd54a4e21e0eb8d8: lunge +3 @ 0316aff84d7c6fed0ec76267a2a9fb7e: evoke +6 @ cb5982e7647e1fb5e9e9b0a5c5fd14b5: cleft +4 @ 20c0f3470139ae163c4b39cc07e914a9: abamp +8 @ 4cd0cc8b708a0ce2bac4ba6503348ab7: bumph +4 @ c4b1c17b0b3d8206f5a098baa170197d: bloom +3 @ 51b86f71b4bcfdfc32cf0871c21315b0: crook +14 @ 677603df2044fe026bf8f0619663dcd3: feted +14 @ 209db4532d787befe47ea070a5dd8932: pownd +2 @ a530ec7ed48a500064fecb0deffc1c12: trice +2 @ df59444aed0a0bbb5de9d63b9cc581c0: fiend +2 @ fd6dcba632f035cb49ec3ab4c29cfd1d: flown +2 @ a7ba31cbed83744667373fcf7c92e19c: query +2 @ 8420025d9e904163177d90020af38fad: merry +5 @ 9ec17907c63984b2f66d2cf07de6bd53: bardy +11 @ c129148ef6411751dd9c9476b527d688: pence +4 @ 9382a8fd7f646f83f978a707477ed321: abaft +2 @ 61592dc0e4a229b06ed1b61ce70aed8d: paddy +2 @ f4d89b73696da579d584073f96176b8b: cruel +8 @ 1e04c82a69577d32121cca378d6c6060: acidy +2 @ f76e4321ed9ec31168e32417cbc995f1: deter +2 @ 3e838421ea267b16aa511cf700025a88: elope +5 @ 6e4ae1e139e4d1e63347a7696add831c: acids +2 @ 2275816ce89842b1ed4bcea0ed4a626c: fairy +2 @ 150147d3739c8f76417927630b18bc9a: ombre +2 @ 7dd7dd71a1c61312b66751c297dd47ba: depth +5 @ 82564c92e65e520fadbaf4ffce3eb31f: perky +13 @ 0be3732d0c397d102b45c45c1c16e3d4: trued +2 @ 7ffea5b88c5fb541163f6a7a6dbdd085: clump +6 @ 0d80721f381f00a58c5d0dcc3cb74197: dight +22 @ d97e59c719d6b6de055179b474eb0044: rewth +2 @ 0af0f0a3ad7e6253f29bd0b8036c7648: melee +7 @ 5f300a0c38c2db8c4cfee542342e5f05: centu +26 @ 564fe5be55e0224f0813fba1f27fae4d: cyton +2 @ 1a92194ac2ec272b346dda0e4fe9d9b8: plied +21 @ 51ef70a95106420fc8ccde3e689fbba1: depth +3 @ e3ff4dad3e257b682910891b3b5ae5a0: islet +2 @ 4ae6522f12fc92507327721ed26590e4: leach +5 @ 9fb32327641a80ed4fad454773da6881: aitch +8 @ b6899e025bda777c308666c9da2b1451: retch +6 @ 4ab6bc9d70154c201db29f9d6f83f37e: handy +5 @ 3b9e5ca31d74869e3025be62ccf1a48f: aswim +5 @ b9011e547784addc06956f2fa544c9d6: howdy +2 @ 8c9beee16562875a0deb41a32a5d83c4: chump +5 @ ae67915ef7a368da901bc12121a8452c: crump +8 @ d75bc6404a3818324e29721d5b70ab3b: cunit +5 @ 4c803334c2ad2084f7d96ad295b720d0: loath +12 @ 2532f33c4420b39801f56213c7ba4da8: gloop +6 @ 2b3a622ecb2fdf4f3bfa40b768802ff1: defog +2 @ 426a7205e79ed54de8531ff208967060: dream +9 @ c70bd671227e80dcf31854dd95c3e066: witty +2 @ 0591adad4d85009292acc4ae4a60be5d: etude +2 @ be6718a7f6500a9b15af8b35a76be103: detox +9 @ 5ad2023cc867c9d6dbf84b20c017dc05: black +2 @ 283c3577d81a2869869b1cd74f9c694b: honor +2 @ dae3a9bd757ff6ab7ee3d3bf6b9e2b9c: mucky +3 @ aed8a405bf79fcf80cfde1569dcfab45: adeem +2 @ da277b752319e8fb9b1182d0f9b334c1: wider +3 @ 6704cd24fa3eb789eedf2d032079c450: abaca +3 @ be4e762a5aff73f1a696e5f2846e53de: aback +2 @ 438505a5441daa6196f8463fed0dd185: cover +3 @ 7aab598cfd1d9a102db4cd71f5497cd2: vying +3 @ 1850dd511371c5158c9973dfc7851b6f: venue +2 @ 34f9b2abaf8c810839f4a1d0fad2337c: flack +2 @ cada2be460afd437bc2a014cc1a1541c: cough +2 @ d3bb478b245c7d89df8409cf2fda93a0: wager +9 @ f1ad15332fd1499cab83e322092aca46: lathy +4 @ 0b226357052e0a1b7474ce8d3ea22073: mount +2 @ 430d6feb5220bcf589942f4ea74de1e9: devil +4 @ 90dc2ff45fc354087e7f6ae84927f375: envoy +2 @ f83cce3d36543aecf0b0568ae6d32a26: rearm +2 @ a1a83c524dd43ef7e5479404ca752c08: diver +6 @ 2e7ceb4cda752ec0e11038b8b868f6f6: throb +26 @ 3e7054532f4963cba462cb07e4f5f47a: meynt +14 @ 6913df2f018015d696786982bd527691: dampy +8 @ 9c7ff8a901d4e029bfd8e77c1e72dad9: badly +4 @ 45f9a7c1c5a6226873f71d88fa19bfcb: aitch +6 @ ebc258250975a8d94854d8322fa05681: abamp +6 @ 4e9c948063ac61b053729f0f91b79fec: adult +3 @ 32ccd94aee82753a0537d1bf342acff4: under +4 @ 36e4921a1177fb3747407acd3be38766: edify +2 @ 2dc2c48faa11a76aedcbbfb94a928df0: water +2 @ 22df59f11c6b201e87c955d7c95e5e94: queue +2 @ f9ee003255a0c8924b65af52693a8df8: erode +15 @ f27762c0973ea0d5ef5bbe36e60faf59: richt +4 @ 7b8bff553837c516211c7ca251b18440: badge +3 @ 28b4c0a82212e7c9eb6fb0092c69dc5f: inbox +5 @ d315ddd434196371e90717a300ee1abb: bufty +4 @ fe00308791484f7d15b7c4c2c1896b80: advew +2 @ dbeb543b352e5faf000e0a34589c780f: musky +2 @ 4f67880639e88a949ea9170f1e40ae3c: meter +3 @ 1a5438cb81dfeff80131ae36f0fee067: gland +2 @ 91cb5cde6cf380c1e81229cea44dcb6c: grace +2 @ de58c54f715a519c04dfdde953e1e1f0: debut +4 @ 1981eeff0ca58429b0530a0d338211ce: capot +5 @ e3a8721e7373f6371032bad58241b068: woven +2 @ 730488f107fe996a36ac7895baf8635e: epoxy +3 @ 2fc13c74761277dfb9fcd3a7cbc00815: piety +10 @ 3935eb0a0ef522991bf42c408f045f44: fudgy +3 @ 4f38c038b8147d0bb780932e191d5b0d: knelt +3 @ 20ace839d583a4ca17c607f35986634c: abaft +2 @ df9c9c48f2a64d9d54f4cd39bafa7fc9: press +6 @ 4f69cba58ce9231d1aef02886c967149: champ +4 @ c0003af3e1d8f171092604d54ceb3166: algid +2 @ e00944e156c950428a58214e494262fc: fecal +7 @ d9ba28ea20a9efe2cbee944f7b043df1: elect +3 @ a421c8dbf696e654048e31f59f48e690: deter +3 @ 304a3b7b8fc3467a378ac531e999786f: eying +3 @ 8223cc4b4916bb574bad52076a9659d1: query +3 @ 80f3d7af440530f31bc3a44d64033960: nanny +3 @ 23263a4b541b41b57b9073579ae2edf3: pesto +8 @ 3c91c76ef603e268b51961bef82c182b: dampy +3 @ eb1a6a321c82a17a944158b9ba189ca0: aduki +3 @ a6a5821183f18cb08d54041bd315f0a6: aband +3 @ 856a7cbe3712d994efb23277501c8fc8: exalt +2 @ fa7f0382bb170d4eadb4fc1f0ffbf6b2: tight +2 @ 0207a7f0b4642882dd35f410e63ae1d7: melon +2 @ 153b4adb59d6d798fdc5baaeba551404: orbit +3 @ 405992a89cf0e2b1da3f2dc318dadf47: awful +5 @ 7087d60cb2ec61ac14aaf709a6fe7d66: aleph +3 @ 88a52d499a2fb0e07658e3d9ef72501c: attap +2 @ 219e19f8d2eaab046778c81bbe94c7ad: lemur +2 @ 6e12fd97b46b4fb8a9a29d34ffb9701d: graft +21 @ dfe3e05baa76bdbc639cd5de6dbddfe1: liman +2 @ 9ede663add59e18911112d7c40b61757: plate +4 @ 6b9c8f08b0e60a6271a7f2c02228910f: conic +6 @ 399f20a95e69559db7fea1b6972027bb: algum +8 @ eaebbac7db75e03439e2a01ab9a8b6bd: dempt +3 @ a9401bbe36edcab9319439269713dcee: proud +4 @ 1c7355160ff899740cbb3e6e3bb71e25: eying +5 @ 84e3da1531d0448bec3a2fe7063a1f85: valor +2 @ 16fd984fcdba4f3f2ba435cc81d6a4ec: inert +2 @ 8b616985b7b3fc998de45744d03d005a: vodka +2 @ cdd9c148cca88261f0b323eea78529bd: condo +2 @ 52b0c226e63a756c66d23f18d504226a: drape +4 @ 23ee5eef465dc66b1faf61023567d926: fleet +3 @ 3f5ddac212b5a920e0a69a031072ba57: tepid +2 @ d9774fb268967324ba3b79569b8eec23: forte +3 @ 678e184ddbeba57c007bc5f3886ad535: abaft +5 @ 90299829fe26540e8d449df7c15a7e5f: aleft +2 @ 2288259ec04ce5839f9c1781eb85901c: grail +3 @ 9375dd5819a89feb4068753fb77d3e1b: renal +2 @ 72f78f3888c63b3678b76a411fbf0868: while +2 @ 038e596e20c37f6b0084066913bf1e4b: trick +2 @ e5704dde2a0e38eb0d54ad64f52665ae: mummy +2 @ a916e4b76f03abf9b1a94b913ce6b597: judge +2 @ 0fad50d0bff790d9d705bd9d3aeff6bd: gauze +4 @ d41ba0c3eee628e78caa98cd6f14b3b2: flume +2 @ 319641d1620afcd16cf588cb6238bae2: glint +3 @ ec8c50a3c63102031a0c56eed65b29aa: vocal +4 @ e1f62af6ece8893c93fae495da6c4efc: aahed +5 @ d446bd4b1ea73988c9699b4cf8bf4c57: plumb +2 @ 005a737c52207cb9a9d2886f3338ee51: gully +3 @ 035a0498db50929c232449a514aad76d: wrong +4 @ 554ab979cc7cf49d8d1a6130201590bf: where +5 @ fb7779ab34f119286d69475e936614e2: rough +3 @ bce83956b7aa5847f6aceb680670ff1f: abysm +2 @ cf777ca91a490bed54c5e2aed4fbaff5: graze +2 @ 3df632913a57c0e954fcb5888128ece4: trout +2 @ 29f7fc3b02147a07c31b783e5297b7a1: tripe +2 @ 4a3eb5416551f0c934bdc866de816adb: quest +2 @ 8b517915da22a344d5ef2bad035dfe15: wreak +2 @ e8c6fd4efd0884a4fbf18069c16e9be2: jazzy +3 @ 4564226cb58a9248fd46b97cf861ad0b: abode +2 @ df168d3cc627ed5ffae81c4f22164abf: genre +2 @ 02fc103d76f0c5c957c6cef1c8c54771: worth +3 @ 569f3327816eea2ce466df7d1c292c28: nymph +3 @ 2de6cef613de83a6f6276c04943993bf: plunk +13 @ 6aaf9a9a017725338e113e8731e352f8: flint +3 @ c9b33b194a4140f88bc4d2d92d3dc21e: valve +2 @ 6135aa72a8ea7906d9f9b3a5b07bbc93: organ +2 @ eba45007c35c8aff7704e7e672bfb3c3: gruel +2 @ bb6285a948e60d3535597acfa4518629: wedge +2 @ ff2e26aab8bae94f998b6837b8aa45fb: oddly +2 @ e5f0a2c80439e4d798ca25f64f8d88c2: wound +2 @ b78ad2fea857055c101ea63151341df7: funny +2 @ 5ef29c06ae31a2aedd1d5e8031b4b590: quiet +3 @ 480154661c4686441688354832c4c24c: mulch +2 @ 1c0618d2f7348c90e22d823f7d0bcf73: trope +2 @ 4afb44cbc5e99848e86044def5d73c4b: howdy +4 @ 398bed08b8933156dd4314d8a0995e07: ample +3 @ 978db2cd8fc86891b1b16e940b008486: widow +2 @ d867f90a185b6bf4033579936110640c: fixer +11 @ 7a3634b532651e2eb6744fb653d552da: pilum +5 @ 002c113db7837984aadebd5926d907a6: party +3 @ 05efc77c959a624c625afea0ad7bea77: worse +2 @ d647adaec6156f656cc1fa92112bb41d: limbo +4 @ 8e68dc965b574c101d686ec11090bc39: fowth +2 @ 8482db72ee509543fb98d3ca1656c924: wimpy +6 @ a019a090d0bbe7bb74f39bdbd54a928e: adown +4 @ 82ae9efd8fd519b0caf8b495e8611f3e: juror +2 @ 299b4a5d44589c224446cdc2ef0ed916: mocha +2 @ 5aeaab2cc9410d12e778fd96b446f051: pooch +2 @ 6cbeed3e0fbde139adcb154fdba3c41f: towel +5 @ e8b272f12f3fe1ad4fac9b7a3f167a46: agila +2 @ 337a4e21a44206e39fbbb09eb4ded44a: pique +3 @ 967d80b59940c6bd96cc7f3cf46c5f41: plait +4 @ c6f312283e6744dde36879401008b4c6: widen +2 @ 9c20ce2964f4d35ef11961ed3798b3c9: minus +3 @ 69ed3ad049c51f0dd2e3bd0f204c21da: raven +2 @ 94cef4cc5941c43c52ac4cb3f9b60b19: hoard +2 @ 36605c5e2db529bfcbf1f179aa7f793e: milky +3 @ 4df1a1a17e1617e5fff5296893d6085a: quick +3 @ 4ac903f846e3fada23b2ea7d5b36a13d: hinge +3 @ 09f8078378614c2168f0bce25729e60c: musky +2 @ 2cab6efcea6f1c55b8e9f527be428e85: layer +3 @ 074529e302b2baee6d79c7a6c76a516e: rhino +2 @ ca47ffbb78beae230fb21817e8cd000a: hover +2 @ cfbffb9d18a359d3210ab7496e68ec5e: latte +2 @ 49cec3070611b693654476db2cef6a14: knelt +2 @ b9b48be944fdec91911c07b01101a221: opium +4 @ 3d598cad7b2bf46ac28779b1e72ce30c: abamp +2 @ 65ebb018a28658ae9b7998c6289cd56e: tulip +5 @ 51be60e0423226428ab1eaa15e24b3d1: point +3 @ 38608e93d30a1eaf2a4ac8e81c61815e: viper +2 @ 1a0244d6da494fdaf7fe552610c612d8: meant +2 @ 451f52fa2ebbf27f93d148ed8cdc349b: limit +3 @ 9b8b8472699a2ba6b6f27139a61c9a67: hobby +2 @ d2de611a0d454fa4681db72b99f853fc: lever +5 @ abd8c224423d43636baf22b275aba848: unwed +3 @ 5f58ded88bb2972929844a7d098bb471: aheap +2 @ f5e8872a6171a0d674a6e45737d9b492: plaza +2 @ 4ed301677a622834e906a0a2622bcdc3: loyal +2 @ f313640a4a7c684b4028c26ed8401ee0: poser +2 @ 946601e09f3ba4c1ca2f30e747cceea4: hussy +2 @ c704255293686169952a058ef7fbe162: unmet +3 @ c0924949ff5c273538786003f5ff2c8f: ajiva +2 @ 33ad79dd3832565ab93e382b46020eb7: lyric +2 @ 78b3d2f6f43d7f9192ad1a7f1bdae4c7: whale +2 @ f6bcc0fffadad6892c0d0a6576a3c8c2: liege +2 @ cab61e6ecbbb9f6ec33b3284dfc5a7a2: piney +3 @ 3ede64974ca3c485383e0d9a909c1693: leaky +3 @ ae745e4aa2241903554ef714097ec89f: abmho +2 @ 6b22e5f7b88a551fe1d12177090e84e4: mayor +2 @ 78239047132297d6804ed3345ce13a20: panic +2 @ 5965a9bbdeb835128bc55bfe38b6618b: pulpy +2 @ dd8e0069af0c7c93e03422ba123f30fc: wiser +2 @ fa71646ed42e4e9c6fe57700dc47b783: lynch +2 @ 526f25b6575fbc76aff691e19c2251c9: noose +3 @ 16222e4402be82218b38f6c0b567d2bc: pubic +2 @ ec20a298f9d78c3bf224f072f57b7dcd: woody +2 @ e8c29e2287874c070b43174e4cfd5d0a: poker +2 @ 68878d648c56699de74880675fcd3f38: tilde +2 @ 7fbc0965a897fd7f274f593b1fb91f7a: rotor +3 @ a2b5c1d2882bdcdd141b8e0fd2a4e836: unfit +2 @ 17472bb73bfa1e95ea8d05c2a9b7509a: jolly +3 @ 406bc995728a801a77bd6c036377d243: merry +2 @ 4aaf4e991ecdd8b0935981c1d5961894: mucus +2 @ 44f8a68f931e081222218c5ec6c7a021: wispy +2 @ 574e92221e7ee4488ecdc9e0a36c5b70: owner +2 @ 1090b4d9e7785059de9373de8c159c61: wacky +2 @ dd8df27f5d8fdc34ab3348b5d839a5e3: older +7 @ 11b20754251b7e5f6c369c34514161a5: exile +2 @ 9d28d41d1514d67f864e725da618f60a: noisy +6 @ 813e5e21f8f1dd0d5727873c81ed769d: verve +2 @ ae5ea2ae53103d778572e3bed46384c5: honey +2 @ 21fef95f8668f363447c71e70c09588a: ovine +2 @ af646f7e902839f73a7752f74cc2be84: phone +2 @ 412ebb3cf9087c4640ce75f5ab1bc6b1: modem +2 @ 707a7c0f499c1a3917fe2f4940d225cd: watch +2 @ e76f47639e64183ac59f8441656b35b1: parer +2 @ 625b7412bdfc7b15464713c161593ff8: poesy +3 @ c63077cc4b4b24e8645cc33ef0d86001: abamp +2 @ 553f90a72ed7c5d93465c0ff4f472658: pivot +2 @ 2d4da6274df6eaebda547918b88d8b88: lumen +2 @ 4d6123fca9b24e32256ffaa974e7d107: peril +4 @ 11d558f04d2f95e11e654e5d1fa37fc5: outgo +6 @ 433b2c3cd20c0be98ce897cc029e26fb: wince +2 @ 6415cd0bdc045724ba0228699b164e4a: otter +2 @ 566ab7c71a901e671edca9a2c597b10b: would +2 @ 1640162b70616d87f78c44bf67c27c58: union +2 @ e8ef9c38e87604d931983aee2bfb5641: tango +2 @ 8541e685abd6a3077a2043a883276b4d: nylon +2 @ e7685c3190e8282a6af05ce68ad36371: vouch +2 @ 2392cfc95587042ec3725555ba0d4036: puppy +2 @ 054fedccf3031cd4809a15dccc0f2c82: prove +2 @ c87872ad60a280e8a26651a62b23073c: ninth +2 @ bf1069cbd3ed3993de486817c36bd9aa: prize +2 @ 977519392e08182d9050018693b07ecf: nicer +25 @ 5e89e887f1003b6be7a6d1e86333d452: butyl +2 @ 8060645d31c0202101fc408a3545e26d: plane +2 @ 193c3643f1213d22ec5ab386bed2bbff: queen +2 @ 1dbc68c0100cc8c7420bbad68d7ef6f0: rajah +3 @ ee9dfbc8431af77cfe06e171481bb63e: retro +2 @ 641deed3c497110d6954d23bbd424d0d: ratty +4 @ 2489b595416aef935b921325b3974d5f: vigor +3 @ 2cfc7f5cb902a5a851c537752ac9a02a: thump +2 @ 54def3204d9660439df9762f79ae0e2d: purge +3 @ 2ff09099afd6d4d4196b5647077e9e49: lemur +2 @ 895fcb31272f9f534a0430e136f792ad: tipsy +4 @ 8a0d2231c6746938f779370a4ec4f189: rapid +4 @ 136300889a3ef47d120504e7ac426d31: remit +4 @ 4685e58446acde44d3f02ed757dfbea5: ached +3 @ 6408be1f68084e187a92db263972b29e: wordy +2 @ 60742fd6ee44ab8d76eaffa46758e52e: trend +3 @ 68d574a60284ddd755b223c7d0af4dc0: saute +2 @ 2e27e38871376041dd96c8e18222a488: racer +2 @ 61a66d29d0d2442d47f1cfed6952738c: revel +2 @ 68cfce017affb663364691af00de57f2: rivet +7 @ 19b4bd4ea36968beb05b9f214d806ab5: fewer +2 @ 3d5aaf4a2c3e23902c21958493693ff2: ratio +4 @ 084d3e095cfd577c7fd12de0c282c2e9: worst +4 @ 0eafa9d3b6ac0326ae44ce145361f6bb: under +3 @ 5ed6094281ab90bff3a62abbbcbc3bc5: arrow +2 @ 6bacd91bbec8651af8efa3ef3fe88944: usher +4 @ b42ad73adc17dcef04ebef5a6298ad95: savoy +2 @ 31be93945cdd09ceba1e81005ed9d5d8: rumba +6 @ f67589a753f5204cfbae14522d002975: bumph +2 @ ef2e524e89dce0922bcc9447d005f345: rider +3 @ 77469faadd2983673fb9032a2a2dc0c6: rover +9 @ 5093d213d6abd4bd03649cc7de76a61a: dempt +8 @ 6fffd23833d80f17389aee5337d404e6: filth +2 @ d84e270992c2ae01010520f49f71a8c7: rumor +2 @ 5f7cef60dea5f7ff8b370af31d6ffa4d: relay +11 @ e406a6e0d197630466d07e4a17fb87ea: kempt +15 @ 948ec09dc5a9e02ae5591c10f3950856: fling +13 @ 3fa0f01055c9e4abe7eeb9637deda30a: newie +2 @ d8ccd056539fccdb1c1ceee9cf30e111: shrew +4 @ 6d38bb2ee8df33ea2d4661c14ec24f9a: acidy +12 @ d903bb76ef9edaddbf8b252043ec9f74: knelt +5 @ 9f25354bd639ecc082e772477c99c806: parer +19 @ a8434b3e58f0928fcc6b944c6ad341cd: dault +2 @ aac703442d0efd34b75a8254d7357e50: shove +2 @ 364ced5082c26e6c2fedb59006b0101a: timer +2 @ 72eb53d6ebe2e67e17ae3cadd0fbfdb5: sauna +2 @ 182eba0a6d5dfcf69218e631f9f868f7: viper +5 @ 4cae0f6d0a9641f9c8491dddf556f219: chant +2 @ ba367d5ca7895b7cd2149443ec4acda1: riser +3 @ 7503db786efbfc9c7c11608fd855fb2c: apish +7 @ f5612690fc91b4d16fb8adff42eb040e: atony +6 @ 4ae4993c962e90571e80b50e3353e026: hanap +9 @ 61dcf095bc690868d8e78440e68d5ed4: butch +2 @ f52851f56ac936bf812b01ac9573e8d9: sever +2 @ 8fb04d53cc9cfcf23cbdd3da142a2e33: sower +23 @ 6d5e7976715c484897a8ca57619436d7: pling +4 @ 931ff635a2c3724a1bc3f1a7e9b1ebdb: spree +2 @ f14b608c591736e648180fdc0ecc7ce6: surge +8 @ 96245740e81d13596e849b3d17c1c1f2: cuppy +37 @ 05c72234998fffd3fff2b8fcf3e58735: cloot +35 @ 72311f66477a6b4d005c574b81384b3e: clipt +2 @ 1bd81ea201d7ed246d3b55b64ee118aa: sweet +2 @ 0dd6a88cd8d95463d677c2a539813b33: sinew +19 @ db2b35153a5ba05c6d930f7ec982833f: thilk +41 @ e1e3fa69650d1b98501e193b4878f9b5: thilk +6 @ e2ae49c1e1c7c1d57642e1c381269562: chant +4 @ a1eefb6692713486960fce4d5c5f1db8: fehme +4 @ 66bd8d2d3682b6a0d0d267a49f7ce217: amped +4 @ 5d571bca0a1c03a882747b5cc0b83984: adapt +3 @ 423ad7f7b86d2719adc047499ce8a58b: ached +3 @ 320e07ab973e8d77cbdc39a0e7adcf5a: smock +2 @ 9cbc21a65a6084c2fc40dbcbfb1b5e63: shank +4 @ 6971a850f5218478de9015dee55c7474: seven +3 @ 0a9385477bd959e1227535c64852b054: spade +2 @ 2accbeb15080f80652c8531505e45fba: scowl +2 @ 987b0b7c93a802b2fe03c03af1283220: shone +3 @ a57ef7bd97f7cb5ec2c4a2a3b8c62c6e: spank +4 @ 952e0c1cebaf0d4d1828dce9fc1adc24: snowy +4 @ 86660f89fe26b2c9651cc20e36ac0bcf: sweep +10 @ c318e2e86c86f3b341b58991789d881e: chant +2 @ d8beaba34de091afca60922f43efa0e1: stake +2 @ e5371bd4028de5596dd489d730290823: swath +2 @ 0202c9f7ef82fcb3a657345ddb409560: steep +4 @ d3e7dfde3112e5fd5378ea509b0c98ff: adept +2 @ 3af6507646bc3dada9e2c39e015f9d60: stank +4 @ b16b32af70a7d01094a9ebe7450a1aaf: acidy +7 @ 67ddaa5c652d2f6846d9b4c75a8c5623: knosp +3 @ ba5e2cf91123cd9e2a05b292cad40bb3: agate +2 @ e38ff4ed48d53e9c314b49b89d350e0d: swash +2 @ 568c5ba4bb6dc5d3edb2692cafa33664: stoop +2 @ 1742a117a6e4b1c8b7d90859a917af70: steal +2 @ 09f2e8e690c178e3f56333cea23d3aad: stern +2 @ f70a20fe38a1a3a11ab0692ffa54634a: swear +4 @ 36d98969eeeb0abb85e54d12390f6d65: ethne +3 @ 0a7aaa5acb2a8533217e58bde82422d4: abysm +3 @ 36f80d4c8ea51551a0d0e4cbcb889656: suite +3 @ b6ad8ce8ba6c6419ccf6fa2cd545a3c8: aback +2 @ 3d93128a3bcfdeb5e91563e61a85a572: stove +4 @ e773c95c714707834a25022a224baa9c: swamp +2 @ 798a0e4af8b5ff3732a45b68eccf8045: swore +63 @ c0e29e6b00cbccce6a33b6e00bf3b646: thilk +2 @ 41bd352341939d69a0b8674255d1d38a: taboo +2 @ e019911c6075d428d5b4d29378c19fab: squib +2 @ 71f95a625999f744877b92c1eb3be0f7: taint +2 @ 5cfc1fb15116244850659f6e9858d187: sixth +3 @ 31ee55867dee5555d80e33786968b7af: abamp +3 @ 9a2ac7fab9fc75dd3223936a86444328: spunk +2 @ dd4f92af1d691e9f9cd26f794fbbc4f0: tatty +2 @ 9ed2768780d89bb3ea0c8c7e65d79765: spoke +3 @ 15250d727c1a4f460c3d39c8d2d6feed: spiky +2 @ ed8d79081a2da000858416c39cc8c681: snail +6 @ 978e052044b6f3f6c082816b7552ea97: aleph +2 @ f285e2cd84572d72db810804f0ab2ece: vital +3 @ 76660dddb1ceb888acec72e4e33d63a1: thyme +3 @ bd23e61709c67cc95cb4cda2ac58512e: tying +2 @ b9b05425499c66a16277767112b6506f: topaz +2 @ 5e175583da8c49b77f4d82f7455fd4e0: timer +4 @ aaff263ca70daf7e4a54d99959d2fddb: thrum +2 @ b3342b199f6ad949ebf8709d27c64f67: wrath +2 @ 126f0424fd87fd3fca1d69be2f0190ac: zesty +2 @ 2e227b635c3121e900fcd25b9ad299da: zonal +2 @ fb282fab1a32f406186a0d5d36c3a44a: treat +2 @ e8ce349c678729d8c7fd625e40a4f389: turbo +2 @ 003872da98976e78f34ab9a8c4bb69bb: wrist +3 @ 9fecdb9e3109b8c6b22141fecf18334d: twine +2 @ fd13c62648af2a18587ed93cb43c7179: villa +2 @ 84c9d16253ea4a1c472cdab45a3a250e: waver +2 @ 5d8ac918ddb67715039c43273a1a2c3a: weedy +3 @ 5bdc58bbaf84d6a0727154f329e891d8: stilt +5 @ 357a02c01e2e869519466c3ccb90af38: swing +2 @ 63287be38534084996f86da5b764fdb3: spire +2 @ 194ed282b5a86a847dc9be76536cdaa1: swine +2 @ 62d5dd583b87675a0a2e3bbb7ee0c1f3: slung +2 @ d54bcf87de8aec779b4a88ecdddade83: sully +2 @ c5c168b1a55a3cd9558bc90b6403e3f1: slink +2 @ 52cf87c94138a89c2709d48b20b0daa2: sling +3 @ 7a7efe909a397da8514f04f4a2c7fc3f: swung +2 @ c1e492708c7fbd20493894c176eec67f: sonar +2 @ 7f666d95c104b23ee32b4b7a506b2670: stain +4 @ e807de2a20dd8756f11d8a3a3a8eaad5: swift +2 @ 3d58429cba5e8c270195c684a50fbc9b: stoic +2 @ 902476ecb724ab3d4c859f0c510d9b39: stony +2 @ 40ebff5e6535975e1b30ee0e792cda4c: stink +2 @ b1f18e59d4b11f58f5731c616748b777: swill +2 @ f26dd211b3edf81ac84481ec004d704f: stunk +5 @ 5d0b1d0441fa6c3df6847b0a1b7754ec: grypt diff --git a/examples/wordle/wordle_solutions.txt b/examples/wordle/wordle_solutions.txt new file mode 100644 index 0000000..4dd830e --- /dev/null +++ b/examples/wordle/wordle_solutions.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 -- 2.45.2