precompute word lettersets
This commit is contained in:
parent
0ce60e52ff
commit
42c1c51e71
1 changed files with 20 additions and 11 deletions
31
src/main.rs
31
src/main.rs
|
|
@ -9,10 +9,14 @@ use crate::letterset::LetterSet;
|
||||||
mod letterset;
|
mod letterset;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let dictionary: Vec<String> = BufReader::new(io::stdin().lock())
|
let dictionary: Vec<_> = BufReader::new(io::stdin().lock())
|
||||||
.lines()
|
.lines()
|
||||||
.collect::<Result<_, _>>()
|
.map(|line| {
|
||||||
.unwrap();
|
let word = line.unwrap();
|
||||||
|
let ls = LetterSet::from(&word);
|
||||||
|
(word, ls)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"{:#?}",
|
"{:#?}",
|
||||||
|
|
@ -23,7 +27,7 @@ fn main() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve(dictionary: &[String], target: LetterSet) -> Option<(u16, Vec<String>)> {
|
fn solve(dictionary: &[(String, LetterSet)], target: LetterSet) -> Option<(u16, Vec<String>)> {
|
||||||
let mut bests = HashMap::new();
|
let mut bests = HashMap::new();
|
||||||
bests.insert(LetterSet::EMPTY, (0, Vec::new()));
|
bests.insert(LetterSet::EMPTY, (0, Vec::new()));
|
||||||
|
|
||||||
|
|
@ -35,7 +39,7 @@ fn solve(dictionary: &[String], target: LetterSet) -> Option<(u16, Vec<String>)>
|
||||||
// length doesn't include spaces. i think that's okay
|
// length doesn't include spaces. i think that's okay
|
||||||
// assumes that `bests[LetterSet::EMPTY] == (0, Vec::new())`
|
// assumes that `bests[LetterSet::EMPTY] == (0, Vec::new())`
|
||||||
fn score(
|
fn score(
|
||||||
dictionary: &[String],
|
dictionary: &[(String, LetterSet)],
|
||||||
bests: &mut HashMap<LetterSet, (u16, Vec<String>)>,
|
bests: &mut HashMap<LetterSet, (u16, Vec<String>)>,
|
||||||
remaining: LetterSet,
|
remaining: LetterSet,
|
||||||
) -> u16 {
|
) -> u16 {
|
||||||
|
|
@ -43,25 +47,30 @@ fn score(
|
||||||
return min.0;
|
return min.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some((word, score)) = dictionary
|
let Some((word, ls, score)) = dictionary
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|word| remaining != remaining.difference(LetterSet::from(word)))
|
.filter(|(_, ls)| !remaining.intersection(*ls).is_empty())
|
||||||
.map(|word| {
|
.map(|(word, ls)| {
|
||||||
(
|
(
|
||||||
word,
|
word,
|
||||||
|
ls,
|
||||||
(u16::try_from(word.len()).unwrap()).saturating_add(score(
|
(u16::try_from(word.len()).unwrap()).saturating_add(score(
|
||||||
dictionary,
|
dictionary,
|
||||||
bests,
|
bests,
|
||||||
remaining.difference(LetterSet::from(word)),
|
remaining.difference(*ls),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.min_by_key(|(_, score)| *score)
|
.min_by_key(|(_, _, score)| *score)
|
||||||
else {
|
else {
|
||||||
return u16::MAX;
|
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
|
let (_score, path) = bests
|
||||||
.get(&remaining_after_word)
|
.get(&remaining_after_word)
|
||||||
.expect("we already inserted this");
|
.expect("we already inserted this");
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue