ineffective noodling
This commit is contained in:
parent
42c1c51e71
commit
4dd2ee21fc
1 changed files with 41 additions and 16 deletions
57
src/main.rs
57
src/main.rs
|
|
@ -1,7 +1,9 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
cmp,
|
||||||
|
collections::{HashMap, hash_map::Entry},
|
||||||
env,
|
env,
|
||||||
io::{self, BufRead, BufReader},
|
io::{self, BufRead, BufReader},
|
||||||
|
process,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::letterset::LetterSet;
|
use crate::letterset::LetterSet;
|
||||||
|
|
@ -9,7 +11,7 @@ use crate::letterset::LetterSet;
|
||||||
mod letterset;
|
mod letterset;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let dictionary: Vec<_> = BufReader::new(io::stdin().lock())
|
let mut dictionary: Vec<_> = BufReader::new(io::stdin().lock())
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| {
|
.map(|line| {
|
||||||
let word = line.unwrap();
|
let word = line.unwrap();
|
||||||
|
|
@ -18,24 +20,46 @@ fn main() {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
println!(
|
let target = env::args().nth(1).map_or(LetterSet::FULL, LetterSet::from);
|
||||||
"{:#?}",
|
println!("letter count: {}", target.len());
|
||||||
solve(
|
let Some((len, path)) = solve(&mut dictionary, target) else {
|
||||||
&dictionary,
|
println!("failed :(");
|
||||||
env::args().nth(1).map_or(LetterSet::FULL, LetterSet::from)
|
process::exit(1);
|
||||||
)
|
};
|
||||||
);
|
println!("{len}: {}", path.join(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve(dictionary: &[(String, LetterSet)], target: LetterSet) -> Option<(u16, Vec<String>)> {
|
fn solve(dictionary: &mut [(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()));
|
||||||
|
|
||||||
|
// WORDS WITH DUPES MUST BE AT THE END!
|
||||||
|
dictionary.sort_by_key(|(word, ls)| {
|
||||||
|
let dupes = word.len() - usize::from(ls.len());
|
||||||
|
(dupes, cmp::Reverse(ls.len()))
|
||||||
|
});
|
||||||
|
|
||||||
|
for (word, ls) in dictionary.iter() {
|
||||||
|
let len = u16::try_from(word.len()).unwrap();
|
||||||
|
match bests.entry(*ls) {
|
||||||
|
Entry::Occupied(mut occupied) => {
|
||||||
|
if occupied.get().0 > len {
|
||||||
|
occupied.insert((len, vec![word.clone()]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Entry::Vacant(vacant) => {
|
||||||
|
vacant.insert((len, vec![word.clone()]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
score(dictionary, &mut bests, target);
|
score(dictionary, &mut bests, target);
|
||||||
|
|
||||||
bests.get(&target).cloned()
|
bests.get(&target).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: perhaps bottom up? (pick or no pick) (real potential!)
|
||||||
|
// the problem is that i'm not *improving* scores, i use the best one immediately
|
||||||
// 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(
|
||||||
|
|
@ -49,16 +73,17 @@ fn score(
|
||||||
|
|
||||||
let Some((word, ls, score)) = dictionary
|
let Some((word, ls, score)) = dictionary
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, ls)| !remaining.intersection(*ls).is_empty())
|
.filter(|(_, ls)| {
|
||||||
|
ls.intersection(remaining.negation()).is_empty()
|
||||||
|
|| !remaining.intersection(*ls).is_empty()
|
||||||
|
//&& ls.intersection(remaining.negation()).len() <= 1
|
||||||
|
})
|
||||||
.map(|(word, ls)| {
|
.map(|(word, ls)| {
|
||||||
|
let rest_score = score(dictionary, bests, remaining.difference(*ls));
|
||||||
(
|
(
|
||||||
word,
|
word,
|
||||||
ls,
|
ls,
|
||||||
(u16::try_from(word.len()).unwrap()).saturating_add(score(
|
(u16::try_from(word.len()).unwrap()).saturating_add(rest_score),
|
||||||
dictionary,
|
|
||||||
bests,
|
|
||||||
remaining.difference(*ls),
|
|
||||||
)),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.min_by_key(|(_, _, score)| *score)
|
.min_by_key(|(_, _, score)| *score)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue