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;
|
||||
|
||||
fn main() {
|
||||
let dictionary: Vec<String> = BufReader::new(io::stdin().lock())
|
||||
let dictionary: Vec<_> = BufReader::new(io::stdin().lock())
|
||||
.lines()
|
||||
.collect::<Result<_, _>>()
|
||||
.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<String>)> {
|
||||
fn solve(dictionary: &[(String, LetterSet)], target: LetterSet) -> Option<(u16, Vec<String>)> {
|
||||
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<String>)>
|
|||
// 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<LetterSet, (u16, Vec<String>)>,
|
||||
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");
|
||||
|
|
|
|||
Loading…
Reference in a new issue