finish day 18 part 1

This commit is contained in:
kageru 2021-12-18 17:37:31 +01:00
parent 68cade10ac
commit 7cbbd03e0f
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2

View File

@ -39,7 +39,7 @@ fn parse_node(raw: &str) -> (Node, usize) {
} }
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Clone, Copy)]
enum Explosion { enum Explosion {
None, None,
Partial, Partial,
@ -52,7 +52,7 @@ impl Node {
} }
fn explode(&mut self) -> bool { fn explode(&mut self) -> bool {
self.explode_inner(0, &mut None, &mut None) != Explosion::None self.explode_inner(0, &mut None, &mut None, Explosion::None) != Explosion::None
} }
fn split(&mut self) -> bool { fn split(&mut self) -> bool {
@ -78,6 +78,7 @@ impl Node {
depth: usize, depth: usize,
previous_number: &'b mut Option<&'a mut usize>, previous_number: &'b mut Option<&'a mut usize>,
for_next: &'b mut Option<usize>, for_next: &'b mut Option<usize>,
state: Explosion,
) -> Explosion { ) -> Explosion {
match (self, &for_next) { match (self, &for_next) {
(Node::Number(n), Some(x)) => { (Node::Number(n), Some(x)) => {
@ -87,25 +88,21 @@ impl Node {
} }
(Node::Number(n), None) => { (Node::Number(n), None) => {
*previous_number = Some(n); *previous_number = Some(n);
Explosion::None state
} }
(s @ Node::Pair(_), _) if depth == 4 => { (s @ Node::Pair(_), _) if depth == 4 && state == Explosion::None => {
let (left, right) = s.number_pair_or_panic(); let (&left, &right) = s.number_pair_or_panic();
if let Some(prev) = previous_number { if let Some(prev) = previous_number {
**prev += left; **prev += left;
} }
*for_next = Some(*right); *for_next = Some(right);
*s = Node::Number(0); *s = Node::Number(0);
Explosion::Partial Explosion::Partial
} }
(Node::Pair(p), _) => { (Node::Pair(p), _) => match p.0.explode_inner(depth + 1, previous_number, for_next, state) {
let left = p.0.explode_inner(depth + 1, previous_number, for_next); f @ Explosion::Full => f,
if left != Explosion::Full { e => p.1.explode_inner(depth + 1, previous_number, for_next, e),
p.1.explode_inner(depth + 1, previous_number, for_next) },
} else {
left
}
}
} }
} }
@ -125,19 +122,13 @@ impl Node {
} }
fn part1(parsed: &Parsed) -> usize { fn part1(parsed: &Parsed) -> usize {
add_and_reduce(parsed.clone()).inspect(|n| println!("{n}")).unwrap().magnitude() add_and_reduce(parsed.clone()).unwrap().magnitude()
} }
fn add_and_reduce(parsed: Parsed) -> Option<Node> { fn add_and_reduce(parsed: Parsed) -> Option<Node> {
/*
let mut r = parsed.into_iter().reduce(move |acc, new| Node::Pair(box (acc, new))).unwrap();
r.reduce();
Some(r)
*/
parsed.into_iter().reduce(move |acc, new| { parsed.into_iter().reduce(move |acc, new| {
let mut n = Node::Pair(box (acc, new)); let mut n = Node::Pair(box (acc, new));
n.reduce(); n.reduce();
println!("{n}");
n n
}) })
} }
@ -205,6 +196,7 @@ mod tests {
#[test_case("[[6,[5,[4,[3,2]]]],1]" => "[[6,[5,[7,0]]],3]")] #[test_case("[[6,[5,[4,[3,2]]]],1]" => "[[6,[5,[7,0]]],3]")]
#[test_case("[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]" => "[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]")] #[test_case("[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]" => "[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]")]
#[test_case("[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]" => "[[3,[2,[8,0]]],[9,[5,[7,0]]]]")] #[test_case("[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]" => "[[3,[2,[8,0]]],[9,[5,[7,0]]]]")]
#[test_case("[[[[4,0],[5,0]],[[[4,5],[2,6]],[9,5]]],[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]]" => "[[[[4,0],[5,4]],[[0,[7,6]],[9,5]]],[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]]")]
fn test_single_explosion(raw: &str) -> String { fn test_single_explosion(raw: &str) -> String {
let mut i = parse_node(raw).0; let mut i = parse_node(raw).0;
assert!(i.explode()); assert!(i.explode());
@ -250,19 +242,35 @@ mod tests {
assert_eq!(res, res2); assert_eq!(res, res2);
} }
#[test]
fn test_single_reduction() {
let mut n = parse_node("[[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]],[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]]").0;
n.reduce();
assert_eq!(n.to_string(), "[[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]");
}
#[test_case("[1,1]\n[2,2]\n[3,3]\n[4,4]" => "[[[[1,1],[2,2]],[3,3]],[4,4]]")] #[test_case("[1,1]\n[2,2]\n[3,3]\n[4,4]" => "[[[[1,1],[2,2]],[3,3]],[4,4]]")]
#[test_case("[1,1]\n[2,2]\n[3,3]\n[4,4]\n[5,5]" => "[[[[3,0],[5,3]],[4,4]],[5,5]]")] #[test_case("[1,1]\n[2,2]\n[3,3]\n[4,4]\n[5,5]" => "[[[[3,0],[5,3]],[4,4]],[5,5]]")]
#[test_case("[1,1]\n[2,2]\n[3,3]\n[4,4]\n[5,5]\n[6,6]" => "[[[[5,0],[7,4]],[5,5]],[6,6]]")] #[test_case("[1,1]\n[2,2]\n[3,3]\n[4,4]\n[5,5]\n[6,6]" => "[[[[5,0],[7,4]],[5,5]],[6,6]]")]
#[test_case("[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]
[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]
[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]
[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]
[7,[5,[[3,8],[1,4]]]]
[[2,[2,2]],[8,[8,1]]]
[2,9]
[1,[[[9,3],9],[[9,0],[0,7]]]]
[[[5,[7,4]],7],1]
[[[[4,2],2],6],[8,7]]" => "[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]")]
fn test_list_reduction(raw: &str) -> String { fn test_list_reduction(raw: &str) -> String {
let parsed = parse_input(raw); let parsed = parse_input(raw);
add_and_reduce(parsed).unwrap().to_string() add_and_reduce(parsed).unwrap().to_string()
} }
test!(part1() == 4140); test!(part1() == 4140);
bench!(part1() == 4173);
bench_input!(Vec::len => 100);
/* /*
bench!(part1() == 0);
bench!(part2() == 0); bench!(part2() == 0);
bench_input!(Vec::len => 0);
*/ */
} }