diff --git a/src/letterset.rs b/src/letterset.rs index 6514499..780db65 100644 --- a/src/letterset.rs +++ b/src/letterset.rs @@ -68,13 +68,6 @@ impl LetterSet { self.0 as usize } - pub fn from_index(index: usize) -> Option { - u32::try_from(index) - .ok() - .filter(|n| *n <= Self::FULL.0) - .map(Self) - } - const fn letter_index(letter: u8) -> Option { if letter.is_ascii_alphabetic() { let lower = letter.to_ascii_lowercase(); @@ -227,12 +220,4 @@ mod test { assert_eq!(ABC.to_index(), 7); assert_eq!(LetterSet::FULL.to_index(), (1 << 26) - 1); } - - #[test] - fn from_index() { - for ls in [LetterSet::EMPTY, A, B, C, AB, AC, BC, ABC, LetterSet::EMPTY] { - assert_eq!(LetterSet::from_index(ls.to_index()), Some(ls)); - } - assert_eq!(LetterSet::from_index(1 << 26), None); - } } diff --git a/src/main.rs b/src/main.rs index 10fb23a..997d08a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,9 +18,13 @@ fn main() { }) .collect(); - let target = env::args().nth(1).map_or(LetterSet::FULL, LetterSet::from); - eprintln!("letter count: {}", target.len()); - let Some((len, path)) = solve(&mut dictionary, target) else { + let search_limit = env::args() + .nth(1) + .and_then(|n| n.parse::().ok()) + .unwrap_or(1000); + + eprintln!("search depth: {search_limit}"); + let Some((len, path)) = solve(&mut dictionary, search_limit) else { println!("failed :("); process::exit(1); }; @@ -29,7 +33,9 @@ fn main() { const MAX_SOLUTION_LENGTH: u8 = 200; -fn solve(dictionary: &mut [(String, LetterSet)], target: LetterSet) -> Option<(u8, Vec<&str>)> { +fn solve(dictionary: &mut [(String, LetterSet)], search_limit: usize) -> Option<(u8, Vec<&str>)> { + let target = LetterSet::FULL; + let mut bests = (0..=LetterSet::FULL.to_index()) .map(|_| (u8::MAX, None)) .collect::>(); @@ -39,7 +45,8 @@ fn solve(dictionary: &mut [(String, LetterSet)], target: LetterSet) -> Option<(u dictionary.sort_by_key(|(word, ls)| word.len() - usize::from(ls.len())); eprintln!("sorted!"); - score(dictionary, &mut bests, target.negation(), 0); + score(dictionary, &mut bests, search_limit, target.negation(), 0); + eprintln!("scored!"); let (len, start) = bests[target.negation().to_index()]; let start = start?; @@ -64,6 +71,7 @@ fn solve(dictionary: &mut [(String, LetterSet)], target: LetterSet) -> Option<(u fn score<'d>( dictionary: &'d [(String, LetterSet)], bests: &mut [(u8, Option<&'d str>)], + search_limit: usize, done_letters: LetterSet, length: u8, ) -> u8 { @@ -85,10 +93,16 @@ fn score<'d>( .map(|(word, ls)| { let word_len = u8::try_from(word.len()).unwrap(); let new_length = word_len.saturating_add(length); - let rest_score = score(dictionary, bests, done_letters.union(*ls), new_length); + let rest_score = score( + dictionary, + bests, + search_limit, + done_letters.union(*ls), + new_length, + ); (word, word_len.saturating_add(rest_score)) }) - .take(1000) + .take(search_limit) .min_by_key(|(_, score)| *score) else { return u8::MAX;