8 releases (breaking)

0.9.0 Mar 6, 2022
0.8.0 Mar 6, 2022
0.7.0 Jan 18, 2022
0.6.0 Jan 16, 2022
0.2.0 Jan 12, 2022

#735 in Science


Used in wordle-solvers

MIT/Apache

41KB
835 lines

wordle-solvers

A Wordle solver

License: MIT OR Apache-2.0


lib.rs:

Building blocks to create a Wordle solver.

This crates provides the type Wordle, which is an Automaton. It accepts only states that satisfy all constraints that are provided from the game.

The expected usage pattern is to search for some accepted state and refine the automaton based on the feedback that the game provides.

Example

use fst::{IntoStreamer, Set, Streamer};
use wordle_automaton::WordleBuilder;

// // Build an FST from a word list - we use some random words
let set = fst::Set::from_iter(&["crush", "morty", "party", "solid"]).unwrap();

// Create an empty Wordle with support for 5 letter words
let wordle = WordleBuilder::<5>::new().build();

// Search with the current Wordle
let mut stream = set.search(wordle.clone()).into_stream();

// Select a guess from the stream
// In the example we take the first one
let guess = stream.next().unwrap();;

// In the first round, the guess is the first word, since all are valid
assert_eq!(guess, b"crush");

// Present the guess to the game and gather feedback
let mut next = WordleBuilder::from(wordle);

// Let's say the correct word is 'party'

// The first letter 'c' is not in the word at all, it can _never_ be a part of the solution
next.never(guess[0]);

// The second letter 'r' is in the word, but in the _wrong position_
// The position is 0-based, corresponding to the byte index
next.wrong_pos(1, guess[1]);

// None of the following letters are part of the solution, we can eliminate them in bulk
next.never_all(&guess[2..]);


// let's try the next round
let wordle = next.build();

let mut stream = set.search(wordle.clone()).into_stream();
let guess = stream.next().unwrap();

// the next valid guess is 'morty' as 'crush' is eliminated, as is 'solid'
assert_eq!(guess, b"morty");

// Present the guess to the game for feedback
let mut next = WordleBuilder::from(wordle);
// 'm' and 'o' are not in 'party'
next.never_all(&guess[..2]);

// The remaining letters are all in their correct position
next.correct_pos(2, guess[2]);
next.correct_pos(3, guess[3]);
next.correct_pos(4, guess[4]);

// Let's try the final round
let wordle = next.build();
let mut stream = set.search(wordle.clone()).into_stream();
let guess = stream.next().unwrap();

// Only 'party' remains as a candidate that fulfills all requirements
assert_eq!(guess, b"party");

// after asking the game, we can verify that we have arrived at a solution
let mut solution = WordleBuilder::from(wordle);
solution.correct_pos(0, guess[0]);
solution.correct_pos(1, guess[1]);

// We don't need to add all the remaining characters, as they are already known to be correct
let solution = solution.build();
assert!(solution.is_solved());
assert_eq!(solution.decode_str(), String::from("party"));

Dependencies

~1.5MB