Use box patterns

This commit is contained in:
kageru 2021-12-18 23:15:37 +01:00
parent 29e0ca1ac9
commit a2c61d1bf4
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2

View File

@ -1,3 +1,4 @@
#![feature(box_patterns)]
#![feature(test)] #![feature(test)]
extern crate test; extern crate test;
use aoc2021::common::*; use aoc2021::common::*;
@ -24,7 +25,7 @@ impl fmt::Display for Node {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self { match &self {
Node::Number(n) => write!(f, "{n}"), Node::Number(n) => write!(f, "{n}"),
Node::Pair(p) => write!(f, "[{},{}]", p.0, p.1), Node::Pair(box (a, b)) => write!(f, "[{a},{b}]"),
} }
} }
} }
@ -68,7 +69,7 @@ impl Node {
*self = Node::Number(*n / 2) + Node::Number(*n / 2 + (*n & 1)); *self = Node::Number(*n / 2) + Node::Number(*n / 2 + (*n & 1));
true true
} }
Node::Pair(p) => p.0.split() || p.1.split(), Node::Pair(box (a, b)) => a.split() || b.split(),
_ => false, _ => false,
} }
} }
@ -76,7 +77,7 @@ impl Node {
fn magnitude(&self) -> usize { fn magnitude(&self) -> usize {
match self { match self {
Node::Number(n) => *n, Node::Number(n) => *n,
Node::Pair(p) => 3 * p.0.magnitude() + 2 * p.1.magnitude(), Node::Pair(box (a, b)) => 3 * a.magnitude() + 2 * b.magnitude(),
} }
} }
@ -87,45 +88,32 @@ impl Node {
for_next: &'b mut Option<usize>, for_next: &'b mut Option<usize>,
state: Explosion, state: Explosion,
) -> Explosion { ) -> Explosion {
match (self, &for_next) { match self {
(Node::Number(n), Some(x)) => { Node::Number(n) => match &for_next {
*n += x; Some(x) => {
*for_next = None; *n += x;
Explosion::Full *for_next = None;
} Explosion::Full
(Node::Number(n), None) => { }
*previous_number = Some(n); None => {
state *previous_number = Some(n);
} state
(s @ Node::Pair(_), _) if depth == 4 && state == Explosion::None => { }
let (&left, &right) = s.number_pair_or_panic(); },
&mut Node::Pair(box (Node::Number(left), Node::Number(right))) if depth == 4 && state == Explosion::None => {
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); *self = Node::Number(0);
Explosion::Partial Explosion::Partial
} }
(Node::Pair(p), _) => match p.0.explode_inner(depth + 1, previous_number, for_next, state) { Node::Pair(box (a, b)) => match a.explode_inner(depth + 1, previous_number, for_next, state) {
f @ Explosion::Full => f, f @ Explosion::Full => f,
e => p.1.explode_inner(depth + 1, previous_number, for_next, e), e => b.explode_inner(depth + 1, previous_number, for_next, e),
}, },
} }
} }
fn number_pair_or_panic(&self) -> (&usize, &usize) {
match &self {
Node::Pair(p) => (p.0.number_or_panic(), p.1.number_or_panic()),
_ => unreachable!(),
}
}
fn number_or_panic(&self) -> &usize {
match &self {
Node::Number(n) => n,
_ => unreachable!(),
}
}
} }
fn part1(parsed: &Parsed) -> usize { fn part1(parsed: &Parsed) -> usize {