From 42c1c51e71339badd667a1c9dc5d98f0ed311231 Mon Sep 17 00:00:00 2001 From: mehbark Date: Tue, 7 Jul 2026 16:12:38 -0400 Subject: [PATCH] precompute word lettersets --- src/main.rs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6ed59d9..c8a029a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,10 +9,14 @@ use crate::letterset::LetterSet; mod letterset; fn main() { - let dictionary: Vec = BufReader::new(io::stdin().lock()) + let dictionary: Vec<_> = BufReader::new(io::stdin().lock()) .lines() - .collect::>() - .unwrap(); + .map(|line| { + let word = line.unwrap(); + let ls = LetterSet::from(&word); + (word, ls) + }) + .collect(); println!( "{:#?}", @@ -23,7 +27,7 @@ fn main() { ); } -fn solve(dictionary: &[String], target: LetterSet) -> Option<(u16, Vec)> { +fn solve(dictionary: &[(String, LetterSet)], target: LetterSet) -> Option<(u16, Vec)> { let mut bests = HashMap::new(); bests.insert(LetterSet::EMPTY, (0, Vec::new())); @@ -35,7 +39,7 @@ fn solve(dictionary: &[String], target: LetterSet) -> Option<(u16, Vec)> // length doesn't include spaces. i think that's okay // assumes that `bests[LetterSet::EMPTY] == (0, Vec::new())` fn score( - dictionary: &[String], + dictionary: &[(String, LetterSet)], bests: &mut HashMap)>, remaining: LetterSet, ) -> u16 { @@ -43,25 +47,30 @@ fn score( return min.0; } - let Some((word, score)) = dictionary + let Some((word, ls, score)) = dictionary .iter() - .filter(|word| remaining != remaining.difference(LetterSet::from(word))) - .map(|word| { + .filter(|(_, ls)| !remaining.intersection(*ls).is_empty()) + .map(|(word, ls)| { ( word, + ls, (u16::try_from(word.len()).unwrap()).saturating_add(score( dictionary, bests, - remaining.difference(LetterSet::from(word)), + remaining.difference(*ls), )), ) }) - .min_by_key(|(_, score)| *score) + .min_by_key(|(_, _, score)| *score) else { return u16::MAX; }; - let remaining_after_word = remaining.difference(LetterSet::from(word)); + if score == u16::MAX { + return score; + } + + let remaining_after_word = remaining.difference(*ls); let (_score, path) = bests .get(&remaining_after_word) .expect("we already inserted this");