fix pattern bug where yellow takes precedence
This commit is contained in:
@@ -2,34 +2,47 @@ use std::{env::args, path::Path};
|
|||||||
|
|
||||||
use wordle_solver::{game::Game, solver::Solver, word_list::WordList};
|
use wordle_solver::{game::Game, solver::Solver, word_list::WordList};
|
||||||
|
|
||||||
pub fn main() {
|
pub fn do_simulation(valid_words: WordList, target_words: WordList, opener: Option<&str>) -> u64 {
|
||||||
let valid_words = WordList::from_file(Path::new("valid-words.txt")).unwrap();
|
|
||||||
let target_words = WordList::from_file(Path::new("answers.txt")).unwrap();
|
|
||||||
let target_word = target_words.random_word();
|
let target_word = target_words.random_word();
|
||||||
|
|
||||||
println!("Target: {}", target_word);
|
println!("Target: {}", target_word);
|
||||||
let mut game = Game::new(target_word);
|
let mut game = Game::new(target_word);
|
||||||
|
|
||||||
let mut solver = Solver::new(valid_words, target_words);
|
let mut solver = Solver::new(valid_words, target_words);
|
||||||
|
|
||||||
if let Some(first_guess) = args().skip(1).next() {
|
if let Some(first_guess) = opener {
|
||||||
if let Some(pat) = game.guess(&first_guess) {
|
match game.guess(&first_guess) {
|
||||||
solver.apply_guess(pat);
|
Ok(pat) => {
|
||||||
println!("{}", solver.tabular_format());
|
solver.apply_guess(pat);
|
||||||
} else {
|
println!("{}", solver.tabular_format());
|
||||||
println!("Found solution: {}", first_guess);
|
}
|
||||||
|
Err(n) => {
|
||||||
|
println!("Found solution at guess {}: {}", n, first_guess);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let best_word = &solver.evaluate_all_words().first().unwrap().clone().word;
|
let best_word = solver.evaluate_all_words().first().unwrap().word.clone();
|
||||||
println!("{}", solver.best_word_format());
|
println!("{}", solver.best_word_format(5));
|
||||||
|
|
||||||
if let Some(pat) = game.guess(best_word) {
|
match game.guess(&best_word) {
|
||||||
solver.apply_guess(pat);
|
Ok(pat) => {
|
||||||
println!("{}", solver.tabular_format());
|
solver.apply_guess(pat);
|
||||||
} else {
|
println!("{}", solver.tabular_format());
|
||||||
println!("Found solution: {}", best_word);
|
}
|
||||||
break;
|
Err(n) => {
|
||||||
|
println!("Found solution at guess {}: {}", n, best_word);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
let valid_words = WordList::from_file(Path::new("valid-words.txt")).unwrap();
|
||||||
|
let target_words = WordList::from_file(Path::new("answers.txt")).unwrap();
|
||||||
|
|
||||||
|
do_simulation(valid_words, target_words, args().skip(1).next().as_deref());
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ pub fn main() {
|
|||||||
|
|
||||||
solver.apply_guess(Pattern::from_guess("CRANE", "CASTS").unwrap());
|
solver.apply_guess(Pattern::from_guess("CRANE", "CASTS").unwrap());
|
||||||
println!("{}", solver.tabular_format());
|
println!("{}", solver.tabular_format());
|
||||||
println!("{}", solver.best_word_format());
|
println!("{}", solver.best_word_format(5));
|
||||||
|
|
||||||
solver.apply_guess(Pattern::from_guess("CRANE", "WORKS").unwrap());
|
solver.apply_guess(Pattern::from_guess("CRANE", "WORKS").unwrap());
|
||||||
println!("{}", solver.tabular_format());
|
println!("{}", solver.tabular_format());
|
||||||
println!("{}", solver.best_word_format());
|
println!("{}", solver.best_word_format(5));
|
||||||
|
|
||||||
solver.apply_guess(Pattern::from_guess("CRANE", "PAPER").unwrap());
|
solver.apply_guess(Pattern::from_guess("CRANE", "PAPER").unwrap());
|
||||||
println!("{}", solver.tabular_format());
|
println!("{}", solver.tabular_format());
|
||||||
println!("{}", solver.best_word_format());
|
println!("{}", solver.best_word_format(5));
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -13,13 +13,13 @@ impl Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn guess(&mut self, word: &str) -> Option<Pattern> {
|
pub fn guess(&mut self, word: &str) -> Result<Pattern, u64> {
|
||||||
self.score += 1;
|
self.score += 1;
|
||||||
|
|
||||||
if word == self.word {
|
if word == self.word {
|
||||||
None
|
Err(self.score)
|
||||||
} else {
|
} else {
|
||||||
Some(Pattern::from_guess(&self.word, word).unwrap())
|
Ok(Pattern::from_guess(&self.word, word).unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-4
@@ -64,8 +64,10 @@ impl Pattern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Yellows
|
|
||||||
for i in 0..chars.len() {
|
for i in 0..chars.len() {
|
||||||
|
if stats[i] == CharStatus::GREEN {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if let Some((j, _)) = rest.iter().enumerate().find(|(_, x)| **x == guess[i]) {
|
if let Some((j, _)) = rest.iter().enumerate().find(|(_, x)| **x == guess[i]) {
|
||||||
stats[i] = CharStatus::YELLOW;
|
stats[i] = CharStatus::YELLOW;
|
||||||
rest[j] = ' ';
|
rest[j] = ' ';
|
||||||
@@ -151,7 +153,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Pattern::from_guess("abcde", "eabcd"),
|
Pattern::from_guess("abcde", "eabcd"),
|
||||||
Pattern::try_new(
|
Pattern::try_new(
|
||||||
"abcde",
|
"eabcd",
|
||||||
vec![
|
vec![
|
||||||
CharStatus::YELLOW,
|
CharStatus::YELLOW,
|
||||||
CharStatus::YELLOW,
|
CharStatus::YELLOW,
|
||||||
@@ -164,7 +166,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Pattern::from_guess("abcde", "fghij"),
|
Pattern::from_guess("abcde", "fghij"),
|
||||||
Pattern::try_new(
|
Pattern::try_new(
|
||||||
"abcde",
|
"fghij",
|
||||||
vec![
|
vec![
|
||||||
CharStatus::GREY,
|
CharStatus::GREY,
|
||||||
CharStatus::GREY,
|
CharStatus::GREY,
|
||||||
@@ -177,7 +179,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Pattern::from_guess("aabbc", "bbaab"),
|
Pattern::from_guess("aabbc", "bbaab"),
|
||||||
Pattern::try_new(
|
Pattern::try_new(
|
||||||
"aabbc",
|
"bbaab",
|
||||||
vec![
|
vec![
|
||||||
CharStatus::YELLOW,
|
CharStatus::YELLOW,
|
||||||
CharStatus::YELLOW,
|
CharStatus::YELLOW,
|
||||||
@@ -189,6 +191,29 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bug_1() {
|
||||||
|
let target = "RARER";
|
||||||
|
let g1 = "RAISE";
|
||||||
|
|
||||||
|
let pat = Pattern::from_guess(target, g1).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
pat,
|
||||||
|
Pattern::try_new(
|
||||||
|
"RAISE",
|
||||||
|
vec![
|
||||||
|
CharStatus::GREEN,
|
||||||
|
CharStatus::GREEN,
|
||||||
|
CharStatus::GREY,
|
||||||
|
CharStatus::GREY,
|
||||||
|
CharStatus::YELLOW,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pattern_match_1() {
|
fn pattern_match_1() {
|
||||||
let p1 = Pattern::try_new(
|
let p1 = Pattern::try_new(
|
||||||
|
|||||||
+4
-6
@@ -80,10 +80,8 @@ impl Solver {
|
|||||||
let expected_score_after_guess = score * solution_probability
|
let expected_score_after_guess = score * solution_probability
|
||||||
+ (1.0 - solution_probability)
|
+ (1.0 - solution_probability)
|
||||||
* (score
|
* (score
|
||||||
+ ((self.valid_words.equal_likelieness_entropy()
|
+ (self.valid_words.equal_likelieness_entropy() - expected_information_gained)
|
||||||
- expected_information_gained)
|
.log2());
|
||||||
.log2()
|
|
||||||
+ 1.0));
|
|
||||||
|
|
||||||
WordStats {
|
WordStats {
|
||||||
word: word.to_string(),
|
word: word.to_string(),
|
||||||
@@ -110,7 +108,7 @@ impl Solver {
|
|||||||
self.best_words.clone()
|
self.best_words.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn best_word_format(&self) -> String {
|
pub fn best_word_format(&self, n: usize) -> String {
|
||||||
let mut table = Table::new("#{:<} {:>} | {:<} {:<} {:<}");
|
let mut table = Table::new("#{:<} {:>} | {:<} {:<} {:<}");
|
||||||
|
|
||||||
table.add_row(
|
table.add_row(
|
||||||
@@ -121,7 +119,7 @@ impl Solver {
|
|||||||
.with_cell("E[I]")
|
.with_cell("E[I]")
|
||||||
.with_cell("E[score]"),
|
.with_cell("E[score]"),
|
||||||
);
|
);
|
||||||
for (i, ws) in self.best_words.iter().take(10).enumerate() {
|
for (i, ws) in self.best_words.iter().take(n).enumerate() {
|
||||||
table.add_row(
|
table.add_row(
|
||||||
Row::new()
|
Row::new()
|
||||||
.with_cell(i + 1)
|
.with_cell(i + 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user