search limit argument

This commit is contained in:
mehbark 2026-07-08 01:03:21 -04:00
parent e8b3dd36cc
commit 42290371eb
2 changed files with 21 additions and 22 deletions

View file

@ -68,13 +68,6 @@ impl LetterSet {
self.0 as usize
}
pub fn from_index(index: usize) -> Option<Self> {
u32::try_from(index)
.ok()
.filter(|n| *n <= Self::FULL.0)
.map(Self)
}
const fn letter_index(letter: u8) -> Option<u8> {
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);
}
}

View file

@ -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::<usize>().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::<Box<[_]>>();
@ -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;