Day 12 Complete. Thanks Reddit. The cache was a godsend!
This commit is contained in:
parent
23b27a2a8a
commit
f287d5a7ee
@ -1,3 +1,5 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::Solution;
|
use super::Solution;
|
||||||
|
|
||||||
pub struct Day12 {}
|
pub struct Day12 {}
|
||||||
@ -18,7 +20,7 @@ impl Solution for Day12 {
|
|||||||
.map(|n| n.parse::<usize>().unwrap())
|
.map(|n| n.parse::<usize>().unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
ans += self.solve(&springs.as_bytes(), None, &nums);
|
ans += self.solve(&springs.as_bytes(), None, &nums, &mut HashMap::new());
|
||||||
}
|
}
|
||||||
Ok(Box::new(ans))
|
Ok(Box::new(ans))
|
||||||
}
|
}
|
||||||
@ -43,7 +45,7 @@ impl Solution for Day12 {
|
|||||||
.map(|n| n.parse::<usize>().unwrap())
|
.map(|n| n.parse::<usize>().unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
ans += self.solve(&springs.as_bytes(), None, &nums);
|
ans += self.solve(&springs.as_bytes(), None, &nums, &mut HashMap::new());
|
||||||
}
|
}
|
||||||
Ok(Box::new(ans))
|
Ok(Box::new(ans))
|
||||||
}
|
}
|
||||||
@ -56,7 +58,13 @@ impl Solution for Day12 {
|
|||||||
impl Day12 {
|
impl Day12 {
|
||||||
/// recursively counts the number of permutations of spring we could get from
|
/// recursively counts the number of permutations of spring we could get from
|
||||||
/// the splits specified in 'nums'
|
/// the splits specified in 'nums'
|
||||||
fn solve(&self, s: &[u8], in_group: Option<usize>, cons: &[usize]) -> usize {
|
fn solve<'a, 'b>(
|
||||||
|
&self,
|
||||||
|
s: &'a [u8],
|
||||||
|
in_group: Option<usize>,
|
||||||
|
cons: &'b [usize],
|
||||||
|
map: &mut HashMap<(&'a [u8], Option<usize>, &'b [usize]), usize>,
|
||||||
|
) -> usize {
|
||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
return match in_group {
|
return match in_group {
|
||||||
Some(n) if cons == &[n] => 1,
|
Some(n) if cons == &[n] => 1,
|
||||||
@ -64,16 +72,37 @@ impl Day12 {
|
|||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Resursively match based on the whether we are in a block and/or we have spaces left to fill
|
|
||||||
match (s[0], in_group, cons) {
|
// Check for a cache hit
|
||||||
(b'.', None, _) | (b'?', None, []) => self.solve(&s[1..], None, cons),
|
if s[0] == b'?' {
|
||||||
(b'.' | b'?', Some(n), [e, ..]) if n == *e => self.solve(&s[1..], None, &cons[1..]),
|
if let Some(result) = map.get(&(s, in_group, cons)) {
|
||||||
(b'#' | b'?', Some(n), [e, ..]) if n < *e => self.solve(&s[1..], Some(n + 1), cons),
|
return *result;
|
||||||
(b'#', None, [_, ..]) => self.solve(&s[1..], Some(1), cons),
|
|
||||||
(b'?', None, _) => self.solve(&s[1..], None, cons) + self.solve(&s[1..], Some(1), cons),
|
|
||||||
_ => 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resursively match based on the whether we are in a block and/or we have spaces left to fill
|
||||||
|
let ans = match (s[0], in_group, cons) {
|
||||||
|
(b'.', None, _) | (b'?', None, []) => self.solve(&s[1..], None, cons, map),
|
||||||
|
(b'.' | b'?', Some(n), [e, ..]) if n == *e => {
|
||||||
|
self.solve(&s[1..], None, &cons[1..], map)
|
||||||
|
}
|
||||||
|
(b'#' | b'?', Some(n), [e, ..]) if n < *e => {
|
||||||
|
self.solve(&s[1..], Some(n + 1), cons, map)
|
||||||
|
}
|
||||||
|
(b'#', None, [_, ..]) => self.solve(&s[1..], Some(1), cons, map),
|
||||||
|
(b'?', None, _) => {
|
||||||
|
self.solve(&s[1..], None, cons, map) + self.solve(&s[1..], Some(1), cons, map)
|
||||||
|
}
|
||||||
|
_ => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store in cache
|
||||||
|
if s[0] == b'?' {
|
||||||
|
map.insert((s, in_group, cons), ans);
|
||||||
|
}
|
||||||
|
|
||||||
|
ans
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test from puzzle input
|
/// Test from puzzle input
|
||||||
|
Loading…
Reference in New Issue
Block a user