Day 18
This commit is contained in:
parent
260f0cd6c3
commit
a8509f694a
|
@ -0,0 +1,100 @@
|
||||||
|
[[[[8,1],8],[[8,1],0]],[[8,[2,4]],[0,8]]]
|
||||||
|
[[[[2,2],[7,4]],[[9,1],6]],8]
|
||||||
|
[[[3,6],[[8,7],[2,9]]],[8,[[2,3],9]]]
|
||||||
|
[[[[4,5],[1,4]],1],[[0,8],[2,[6,8]]]]
|
||||||
|
[[7,[[4,6],[0,0]]],[[4,3],5]]
|
||||||
|
[[[[8,4],4],[[4,4],[1,0]]],[[5,[5,5]],[[5,2],1]]]
|
||||||
|
[[[0,[5,8]],[1,7]],[[[5,0],[1,3]],7]]
|
||||||
|
[4,[[[6,2],[7,8]],[0,[4,4]]]]
|
||||||
|
[[[3,[5,3]],8],[[[6,8],4],[8,9]]]
|
||||||
|
[[[6,0],[9,[8,1]]],[[[9,7],3],0]]
|
||||||
|
[[9,[[9,3],[0,8]]],[[[5,3],0],[[5,6],2]]]
|
||||||
|
[[3,[[7,7],3]],[[7,[5,2]],[[6,9],0]]]
|
||||||
|
[1,[4,[3,8]]]
|
||||||
|
[[[[0,2],9],[[0,7],8]],[[5,4],[2,8]]]
|
||||||
|
[[[[1,8],9],[1,7]],[[4,[8,5]],[[6,3],[1,0]]]]
|
||||||
|
[[9,[[4,3],[3,3]]],[[[4,9],[0,9]],6]]
|
||||||
|
[7,[[8,0],[5,6]]]
|
||||||
|
[[[[3,2],1],[[4,9],6]],[[9,[1,1]],[[8,7],1]]]
|
||||||
|
[[[[5,1],[3,3]],0],[1,[[3,2],2]]]
|
||||||
|
[[7,9],[[9,9],[5,[9,5]]]]
|
||||||
|
[[[[4,3],[1,7]],[4,[9,2]]],[[6,[1,7]],[[8,0],3]]]
|
||||||
|
[[[5,[2,8]],[[1,2],7]],[[3,[0,5]],[[3,5],8]]]
|
||||||
|
[[[[2,2],6],[[2,1],7]],[[[4,6],8],7]]
|
||||||
|
[[2,[[3,0],[0,5]]],[[[3,4],[0,1]],0]]
|
||||||
|
[[[[9,9],5],[[9,9],6]],[[[4,1],2],0]]
|
||||||
|
[4,[[2,9],[6,2]]]
|
||||||
|
[[[8,6],6],7]
|
||||||
|
[[7,[8,2]],[[[5,5],6],[9,0]]]
|
||||||
|
[5,[[2,5],[[4,9],[8,6]]]]
|
||||||
|
[[4,[7,[9,6]]],7]
|
||||||
|
[[[9,[3,3]],[[3,1],[8,7]]],[[6,[3,5]],[4,1]]]
|
||||||
|
[[8,6],[8,[[0,2],[8,1]]]]
|
||||||
|
[6,[8,[[7,7],0]]]
|
||||||
|
[3,4]
|
||||||
|
[[9,[8,0]],[[[7,8],3],1]]
|
||||||
|
[5,[[3,[8,7]],[[5,0],[9,7]]]]
|
||||||
|
[[[[4,2],9],[6,[0,2]]],6]
|
||||||
|
[[4,[3,[4,9]]],[[4,[1,6]],1]]
|
||||||
|
[[[6,3],[8,8]],[5,[[9,3],[6,3]]]]
|
||||||
|
[[[9,9],[[7,1],6]],[[[1,0],[7,4]],[3,[2,0]]]]
|
||||||
|
[[[[2,5],9],[3,[6,2]]],[4,7]]
|
||||||
|
[[1,[7,8]],[[[0,1],8],[[1,1],9]]]
|
||||||
|
[[[9,[6,4]],[[9,8],[0,2]]],[[[8,9],[2,3]],[3,[8,0]]]]
|
||||||
|
[[[[6,8],2],3],[[2,2],5]]
|
||||||
|
[[[4,[8,5]],[[4,3],1]],[[[2,4],[4,4]],[[4,1],[1,7]]]]
|
||||||
|
[[[[2,6],6],[[9,2],4]],[[[9,9],[9,5]],5]]
|
||||||
|
[[[[7,5],[4,9]],4],[[[0,7],[3,6]],[[6,5],[3,0]]]]
|
||||||
|
[[[4,4],[[5,7],[8,5]]],[0,8]]
|
||||||
|
[[3,[[1,3],[7,5]]],[6,[[8,1],0]]]
|
||||||
|
[[[9,9],[5,[9,6]]],[[[4,0],[5,4]],6]]
|
||||||
|
[0,[[[9,2],4],3]]
|
||||||
|
[[[1,[8,5]],[0,[6,0]]],[[[6,5],[3,1]],[[6,2],[1,5]]]]
|
||||||
|
[[[4,0],[4,7]],6]
|
||||||
|
[1,[[[5,2],9],[[3,9],4]]]
|
||||||
|
[[[[9,6],[4,1]],4],[2,[[0,2],6]]]
|
||||||
|
[9,[[[1,5],[3,1]],1]]
|
||||||
|
[5,0]
|
||||||
|
[9,[[[7,5],[2,1]],[[2,3],[5,3]]]]
|
||||||
|
[[5,[[0,5],[9,5]]],[[[2,7],3],[[2,9],[3,5]]]]
|
||||||
|
[[[1,9],2],[[7,[1,7]],[8,[9,8]]]]
|
||||||
|
[[8,9],[[5,[9,0]],[[6,8],[5,2]]]]
|
||||||
|
[6,[[[1,3],[0,8]],4]]
|
||||||
|
[[[[9,8],[0,9]],[[8,4],[3,5]]],[[[5,0],8],[[6,8],1]]]
|
||||||
|
[[6,[[1,4],[7,0]]],[[3,4],[[2,1],[2,7]]]]
|
||||||
|
[[[5,0],[3,[4,7]]],[[9,3],[[9,4],[9,6]]]]
|
||||||
|
[[[[8,3],[8,0]],5],[[[5,5],[0,2]],[[0,1],9]]]
|
||||||
|
[[[[6,4],[1,8]],[3,[0,2]]],[8,[[8,8],5]]]
|
||||||
|
[2,[[2,1],[1,4]]]
|
||||||
|
[8,[0,[3,5]]]
|
||||||
|
[[[[0,2],3],[[4,9],[1,2]]],[[8,2],[6,[7,1]]]]
|
||||||
|
[[[0,0],9],1]
|
||||||
|
[8,[[4,1],[[1,3],9]]]
|
||||||
|
[[[8,[5,9]],9],[[[5,7],[9,0]],3]]
|
||||||
|
[[5,[2,9]],7]
|
||||||
|
[5,6]
|
||||||
|
[[[[7,5],[8,3]],[[4,3],8]],[[2,2],[[7,2],[4,2]]]]
|
||||||
|
[[[9,5],[3,[1,5]]],6]
|
||||||
|
[[[[7,4],[7,9]],[[3,1],[3,1]]],[[[6,4],[0,1]],1]]
|
||||||
|
[[3,[[7,4],9]],[[[5,8],[2,7]],[[0,4],[3,6]]]]
|
||||||
|
[[[3,[2,3]],[[6,0],[7,7]]],1]
|
||||||
|
[[2,[[8,8],[2,3]]],[5,2]]
|
||||||
|
[[[0,[5,5]],[8,1]],5]
|
||||||
|
[[3,9],[6,[[0,5],[1,7]]]]
|
||||||
|
[[[[3,0],9],[8,2]],[[[2,2],8],0]]
|
||||||
|
[[[9,6],[[5,1],[4,9]]],[[[1,1],[0,3]],[[4,9],[7,5]]]]
|
||||||
|
[[[2,[6,1]],[[5,7],[9,2]]],[[[4,2],8],9]]
|
||||||
|
[[9,[7,1]],[[4,5],[9,1]]]
|
||||||
|
[[9,[5,0]],[[1,7],[[9,6],[4,5]]]]
|
||||||
|
[[[[1,1],[8,7]],4],[[0,4],[[1,7],[3,5]]]]
|
||||||
|
[[5,[1,[8,4]]],[[[9,4],0],[1,[5,5]]]]
|
||||||
|
[[[5,[1,6]],[6,0]],[[0,[9,7]],1]]
|
||||||
|
[2,[9,[[0,3],[2,3]]]]
|
||||||
|
[3,[4,[[0,9],8]]]
|
||||||
|
[[5,6],[[[9,9],[4,0]],[7,[2,0]]]]
|
||||||
|
[[[[5,1],6],[[1,0],[7,1]]],[[6,[1,0]],[[4,2],[0,0]]]]
|
||||||
|
[[[4,[0,2]],6],[[[4,3],[8,0]],[[9,6],[1,5]]]]
|
||||||
|
[[[[5,3],[2,2]],[8,[8,3]]],[[9,1],2]]
|
||||||
|
[[3,4],[[[4,7],[2,3]],[9,[9,0]]]]
|
||||||
|
[[[5,[6,2]],[[1,5],[9,2]]],[[[7,9],3],[[6,7],[6,2]]]]
|
||||||
|
[[[5,3],9],[[2,[4,3]],[[5,3],1]]]
|
|
@ -0,0 +1,565 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
pub fn day18() {
|
||||||
|
assert_eq!(
|
||||||
|
parse("[[1,2],3]"),
|
||||||
|
SnailNum {
|
||||||
|
tokens: vec![
|
||||||
|
Token::Start,
|
||||||
|
Token::Start,
|
||||||
|
Token::Number(1),
|
||||||
|
Token::Number(2),
|
||||||
|
Token::End,
|
||||||
|
Token::Number(3),
|
||||||
|
Token::End,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let pairs = [
|
||||||
|
("[[[[[9,8],1],2],3],4]", "[[[[0,9],2],3],4]"),
|
||||||
|
("[7,[6,[5,[4,[3,2]]]]]", "[7,[6,[5,[7,0]]]]"),
|
||||||
|
("[[6,[5,[4,[3,2]]]],1]", "[[6,[5,[7,0]]],3]"),
|
||||||
|
(
|
||||||
|
"[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]",
|
||||||
|
"[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]",
|
||||||
|
"[[3,[2,[8,0]]],[9,[5,[7,0]]]]",
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (input, expected) in pairs {
|
||||||
|
let mut num = parse(input);
|
||||||
|
assert!(num.try_explode());
|
||||||
|
assert_eq!(num, parse(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
parse("[[[[4,3],4],4],[7,[[8,4],9]]]").add(parse("[1,1]")),
|
||||||
|
parse("[[[[0,7],4],[[7,8],[6,0]]],[8,1]]")
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert_eq!(
|
||||||
|
// sum_all(&["[1,1]", "[2,2]", "[3,3]", "[4,4]"]),
|
||||||
|
// parse("[[[[1,1],[2,2]],[3,3]],[4,4]]")
|
||||||
|
// );
|
||||||
|
// assert_eq!(
|
||||||
|
// sum_all(&["[1,1]", "[2,2]", "[3,3]", "[4,4]", "[5,5]"]),
|
||||||
|
// parse("[[[[3,0],[5,3]],[4,4]],[5,5]]")
|
||||||
|
// );
|
||||||
|
// assert_eq!(
|
||||||
|
// sum_all(&["[1,1]", "[2,2]", "[3,3]", "[4,4]", "[5,5]", "[6,6]"]),
|
||||||
|
// parse("[[[[5,0],[7,4]],[5,5]],[6,6]]")
|
||||||
|
// );
|
||||||
|
|
||||||
|
assert_eq!(parse("[[1,2],[[3,4],5]]").magnitude(), 143);
|
||||||
|
assert_eq!(parse("[[[[0,7],4],[[7,8],[6,0]]],[8,1]]").magnitude(), 1384);
|
||||||
|
assert_eq!(
|
||||||
|
parse("[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]").magnitude(),
|
||||||
|
3488
|
||||||
|
);
|
||||||
|
|
||||||
|
let input = include_str!("../input/day18.txt");
|
||||||
|
let nums = input.trim().lines().map(|l| parse(l.trim()));
|
||||||
|
let sum = nums.clone().reduce(|a, b| a.add(b)).unwrap();
|
||||||
|
println!("part 1: {}", sum.magnitude());
|
||||||
|
|
||||||
|
let max_sum_magnitude = nums
|
||||||
|
.clone()
|
||||||
|
.cartesian_product(nums)
|
||||||
|
.map(|(a, b)| a.add(b).magnitude())
|
||||||
|
.max()
|
||||||
|
.unwrap();
|
||||||
|
println!("part 2: {}", max_sum_magnitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
struct SnailNum {
|
||||||
|
tokens: Vec<Token>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
enum Token {
|
||||||
|
Start,
|
||||||
|
End,
|
||||||
|
Number(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Token {
|
||||||
|
fn is_num(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Token::Number(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_num(&self) -> &usize {
|
||||||
|
match self {
|
||||||
|
Token::Number(n) => n,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_num_mut(&mut self) -> &mut usize {
|
||||||
|
match self {
|
||||||
|
Token::Number(n) => n,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(s: &str) -> SnailNum {
|
||||||
|
let mut v = vec![];
|
||||||
|
let mut it = s.chars().peekable();
|
||||||
|
let mut depth = 0;
|
||||||
|
while let Some(c) = it.next() {
|
||||||
|
match c {
|
||||||
|
'[' => {
|
||||||
|
depth += 1;
|
||||||
|
v.push(Token::Start);
|
||||||
|
}
|
||||||
|
']' => {
|
||||||
|
depth -= 1;
|
||||||
|
v.push(Token::End);
|
||||||
|
}
|
||||||
|
',' => (),
|
||||||
|
'0'..='9' => {
|
||||||
|
let mut n = c.to_digit(10).unwrap() as usize;
|
||||||
|
while let Some(c @ '0'..='9') = it.peek() {
|
||||||
|
n *= 10;
|
||||||
|
n += c.to_digit(10).unwrap() as usize;
|
||||||
|
it.next();
|
||||||
|
}
|
||||||
|
v.push(Token::Number(n));
|
||||||
|
}
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_eq!(depth, 0);
|
||||||
|
SnailNum { tokens: v }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for SnailNum {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
enum State {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
let mut state = VecDeque::new();
|
||||||
|
for (i, t) in self.tokens.iter().enumerate() {
|
||||||
|
match t {
|
||||||
|
Token::Start => {
|
||||||
|
write!(f, "[").expect("write");
|
||||||
|
state.push_front(State::Left);
|
||||||
|
}
|
||||||
|
Token::End => {
|
||||||
|
write!(f, "]").expect("write");
|
||||||
|
if state.pop_front().unwrap() == State::Left {
|
||||||
|
if i < self.tokens.len() - 1 {
|
||||||
|
write!(f, ",").expect("write");
|
||||||
|
}
|
||||||
|
state.push_front(State::Right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Token::Number(n) => {
|
||||||
|
write!(f, "{}", n).expect("write");
|
||||||
|
if state.pop_front().unwrap() == State::Left {
|
||||||
|
write!(f, ",").expect("write");
|
||||||
|
state.push_front(State::Right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(state.is_empty());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SnailNum {
|
||||||
|
fn magnitude(&self) -> usize {
|
||||||
|
let mut tokens = self.tokens.clone();
|
||||||
|
while tokens.len() != 1 {
|
||||||
|
let mut first_of_two_numbers: Option<usize> = None;
|
||||||
|
for i in (0..tokens.len() - 2).rev() {
|
||||||
|
if !tokens[i].is_num() || !tokens[i + 1].is_num() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
first_of_two_numbers = Some(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let i = first_of_two_numbers.unwrap();
|
||||||
|
let mag = 3 * *tokens[i].as_num_mut() + 2 * *tokens[i + 1].as_num_mut();
|
||||||
|
tokens.splice(i - 1..=i + 2, [Token::Number(mag)]);
|
||||||
|
}
|
||||||
|
*tokens.first().unwrap().as_num()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(mut self, mut other: SnailNum) -> SnailNum {
|
||||||
|
let mut tokens = vec![];
|
||||||
|
tokens.push(Token::Start);
|
||||||
|
tokens.append(&mut self.tokens);
|
||||||
|
tokens.append(&mut other.tokens);
|
||||||
|
tokens.push(Token::End);
|
||||||
|
let mut new = SnailNum { tokens };
|
||||||
|
new.reduce();
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce(&mut self) {
|
||||||
|
loop {
|
||||||
|
if self.try_explode() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if self.try_split() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_explode(&mut self) -> bool {
|
||||||
|
let mut depth = 0;
|
||||||
|
let mut exploding_start_index: Option<usize> = None;
|
||||||
|
for (i, t) in self.tokens.iter().enumerate() {
|
||||||
|
if t == &Token::Start {
|
||||||
|
depth += 1;
|
||||||
|
if depth > 4 {
|
||||||
|
exploding_start_index = Some(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if t == &Token::End {
|
||||||
|
depth -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(index) = exploding_start_index {
|
||||||
|
let l = *self.tokens[index + 1].as_num_mut();
|
||||||
|
let r = *self.tokens[index + 2].as_num_mut();
|
||||||
|
|
||||||
|
let mut prev_num_index = Some(index - 1);
|
||||||
|
let mut next_num_index = Some(index + 4);
|
||||||
|
loop {
|
||||||
|
if prev_num_index.is_none() || self.tokens[prev_num_index.unwrap()].is_num() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_num_index = prev_num_index.unwrap().checked_sub(1);
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
if self.tokens[next_num_index.unwrap()].is_num() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let next = next_num_index.unwrap() + 1;
|
||||||
|
if next >= self.tokens.len() {
|
||||||
|
next_num_index = None;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
next_num_index = Some(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(i) = prev_num_index {
|
||||||
|
*self.tokens[i].as_num_mut() += l;
|
||||||
|
}
|
||||||
|
if let Some(i) = next_num_index {
|
||||||
|
*self.tokens[i].as_num_mut() += r;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tokens.splice(index..=index + 3, [Token::Number(0)]);
|
||||||
|
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_split(&mut self) -> bool {
|
||||||
|
let mut index = 0;
|
||||||
|
loop {
|
||||||
|
if index >= self.tokens.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let Token::Number(10..) = self.tokens[index] {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let old = *self.tokens[index].as_num_mut();
|
||||||
|
let half = (old as f64) / 2_f64;
|
||||||
|
self.tokens.splice(
|
||||||
|
index..=index,
|
||||||
|
[
|
||||||
|
Token::Start,
|
||||||
|
Token::Number(half.floor() as usize),
|
||||||
|
Token::Number(half.ceil() as usize),
|
||||||
|
Token::End,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// use std::cell::{Cell, Ref, RefCell};
|
||||||
|
// use std::collections::VecDeque;
|
||||||
|
// use std::fmt::Display;
|
||||||
|
// use std::iter::Peekable;
|
||||||
|
|
||||||
|
// pub fn day18() {
|
||||||
|
// assert_eq!(
|
||||||
|
// SnailNum::from("[[1,2],3]"),
|
||||||
|
// SnailNum {
|
||||||
|
// left: NumOrSnail::Snail(
|
||||||
|
// SnailNum {
|
||||||
|
// left: NumOrSnail::Num(1.into()).into(),
|
||||||
|
// right: NumOrSnail::Num(2.into()).into()
|
||||||
|
// }
|
||||||
|
// .into()
|
||||||
|
// )
|
||||||
|
// .into(),
|
||||||
|
// right: NumOrSnail::Num(3.into()).into(),
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// assert_eq!(
|
||||||
|
// SnailNum::from("[1,2]").add(SnailNum::from("[[3,4],5]")),
|
||||||
|
// SnailNum {
|
||||||
|
// left: NumOrSnail::Snail(
|
||||||
|
// SnailNum {
|
||||||
|
// left: NumOrSnail::Num(1.into()).into(),
|
||||||
|
// right: NumOrSnail::Num(2.into()).into(),
|
||||||
|
// }
|
||||||
|
// .into()
|
||||||
|
// )
|
||||||
|
// .into(),
|
||||||
|
// right: NumOrSnail::Snail(
|
||||||
|
// SnailNum {
|
||||||
|
// left: NumOrSnail::Snail(
|
||||||
|
// SnailNum {
|
||||||
|
// left: NumOrSnail::Num(3.into()).into(),
|
||||||
|
// right: NumOrSnail::Num(4.into()).into(),
|
||||||
|
// }
|
||||||
|
// .into()
|
||||||
|
// )
|
||||||
|
// .into(),
|
||||||
|
// right: NumOrSnail::Num(5.into()).into(),
|
||||||
|
// }
|
||||||
|
// .into()
|
||||||
|
// )
|
||||||
|
// .into()
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// let mut sn = SnailNum::from("[[6,[5,[4,[3,2]]]],1]");
|
||||||
|
// sn.reduce();
|
||||||
|
// println!("{}", sn);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn parse_snail_num(s: &mut Peekable<impl Iterator<Item = char>>) -> SnailNum {
|
||||||
|
// assert_eq!(s.next(), Some('['));
|
||||||
|
// let left: NumOrSnail;
|
||||||
|
// match s.peek() {
|
||||||
|
// Some('[') => left = NumOrSnail::Snail(Box::new(parse_snail_num(s))),
|
||||||
|
// Some(_) => left = NumOrSnail::Num(parse_num(s).into()),
|
||||||
|
// None => panic!(),
|
||||||
|
// }
|
||||||
|
// assert_eq!(s.next(), Some(','));
|
||||||
|
// let right: NumOrSnail;
|
||||||
|
// match s.peek() {
|
||||||
|
// Some('[') => right = NumOrSnail::Snail(Box::new(parse_snail_num(s))),
|
||||||
|
// Some(_) => right = NumOrSnail::Num(parse_num(s).into()),
|
||||||
|
// None => panic!(),
|
||||||
|
// }
|
||||||
|
// assert_eq!(s.next(), Some(']'));
|
||||||
|
// SnailNum {
|
||||||
|
// left: left.into(),
|
||||||
|
// right: right.into(),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn parse_num(s: &mut Peekable<impl Iterator<Item = char>>) -> usize {
|
||||||
|
// let mut res = 0;
|
||||||
|
// while let Some('0'..='9') = s.peek() {
|
||||||
|
// let digit = s.next().unwrap().to_digit(10);
|
||||||
|
// res *= 10;
|
||||||
|
// res += digit.unwrap() as usize;
|
||||||
|
// }
|
||||||
|
// res
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[derive(Debug, PartialEq)]
|
||||||
|
// struct SnailNum {
|
||||||
|
// left: RefCell<NumOrSnail>,
|
||||||
|
// right: RefCell<NumOrSnail>,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[derive(Debug, PartialEq)]
|
||||||
|
// enum NumOrSnail {
|
||||||
|
// Num(Cell<usize>),
|
||||||
|
// Snail(Box<SnailNum>),
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
// enum Side {
|
||||||
|
// Left,
|
||||||
|
// Right,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl SnailNum {
|
||||||
|
// fn add(self, other: SnailNum) -> SnailNum {
|
||||||
|
// SnailNum {
|
||||||
|
// left: NumOrSnail::Snail(Box::new(self)).into(),
|
||||||
|
// right: NumOrSnail::Snail(Box::new(other)).into(),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn reduce(&mut self) {
|
||||||
|
// loop {
|
||||||
|
// if self.try_explode() {
|
||||||
|
// continue;
|
||||||
|
// } else if self.try_split() {
|
||||||
|
// continue;
|
||||||
|
// } else {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn try_explode(&mut self) -> bool {
|
||||||
|
// let mut queue: VecDeque<(&SnailNum, Vec<(Ref<'_, &SnailNum>, Side)>, usize)> =
|
||||||
|
// VecDeque::new();
|
||||||
|
// queue.push_back((self, vec![], 0));
|
||||||
|
// while let Some((item, mut parents, depth)) = queue.pop_front() {
|
||||||
|
// if depth >= 4 {
|
||||||
|
// let l = item.left.borrow().as_num();
|
||||||
|
// let r = item.right.borrow().as_num();
|
||||||
|
// // add item's right to next leaf to the right:
|
||||||
|
// // go up until we're the left child then go back down to find the leftmost leaf of the right child
|
||||||
|
// // and similarly for item's left to next leaf to the left
|
||||||
|
// let mut immediate_parent: Option<(&SnailNum, Side)> = None;
|
||||||
|
// let mut left_parent: Option<&SnailNum> = None;
|
||||||
|
// let mut right_parent: Option<&SnailNum> = None;
|
||||||
|
// while let Some((p, side)) = parents.pop() {
|
||||||
|
// if immediate_parent.is_none() {
|
||||||
|
// immediate_parent = Some((p, side));
|
||||||
|
// }
|
||||||
|
// if left_parent.is_none() && side == Side::Left {
|
||||||
|
// left_parent = Some(p);
|
||||||
|
// } else if right_parent.is_none() && side == Side::Right {
|
||||||
|
// right_parent = Some(p);
|
||||||
|
// }
|
||||||
|
// if left_parent.is_some() && right_parent.is_some() {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if let Some(left_parent) = left_parent {
|
||||||
|
// left_parent.right.borrow().add_to_leftmost_leaf(r);
|
||||||
|
// }
|
||||||
|
// if let Some(right_parent) = right_parent {
|
||||||
|
// right_parent.left.borrow().add_to_rightmost_leaf(l);
|
||||||
|
// }
|
||||||
|
// // replace item with 0
|
||||||
|
// match immediate_parent.unwrap().1 {
|
||||||
|
// Side::Left => {
|
||||||
|
// *immediate_parent.unwrap().0.left.borrow_mut() = NumOrSnail::Num(0.into());
|
||||||
|
// }
|
||||||
|
// Side::Right => {
|
||||||
|
// *immediate_parent.unwrap().0.right.borrow_mut() = NumOrSnail::Num(0.into());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// } else {
|
||||||
|
// // add right first so that left is at the front of the queue
|
||||||
|
// let right_borrowed = item.right.borrow();
|
||||||
|
// if let Some(right) = right_borrowed.as_snail() {
|
||||||
|
// let mut v = parents.clone();
|
||||||
|
// v.push((item, Side::Right));
|
||||||
|
// queue.push_front((right, v, depth + 1));
|
||||||
|
// }
|
||||||
|
// // if let NumOrSnail::Snail(left) = &item.left {
|
||||||
|
// // let mut v = parents.clone();
|
||||||
|
// // v.push((item, Side::Left));
|
||||||
|
// // queue.push_front((left.as_ref(), v, depth + 1));
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// false
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn add_to_leftmost_leaf(&self, amt: usize) {
|
||||||
|
// self.left.borrow().add_to_leftmost_leaf(amt);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn add_to_rightmost_leaf(&self, amt: usize) {
|
||||||
|
// self.right.borrow().add_to_rightmost_leaf(amt);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn try_split(&mut self) -> bool {
|
||||||
|
// false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl From<&str> for SnailNum {
|
||||||
|
// fn from(s: &str) -> Self {
|
||||||
|
// parse_snail_num(&mut s.chars().peekable())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl Display for SnailNum {
|
||||||
|
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
// write!(f, "[").expect("write");
|
||||||
|
// write!(f, "{}", self.left.borrow()).expect("write");
|
||||||
|
// write!(f, ",").expect("write");
|
||||||
|
// write!(f, "{}", self.right.borrow()).expect("write");
|
||||||
|
// write!(f, "]").expect("write");
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl NumOrSnail {
|
||||||
|
// fn as_num(&self) -> usize {
|
||||||
|
// match self {
|
||||||
|
// NumOrSnail::Num(n) => n.get(),
|
||||||
|
// _ => panic!(),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn as_snail(&self) -> Option<&SnailNum> {
|
||||||
|
// match self {
|
||||||
|
// NumOrSnail::Snail(b) => Some(b),
|
||||||
|
// _ => None,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn add_to_leftmost_leaf(&self, amt: usize) {
|
||||||
|
// match self {
|
||||||
|
// NumOrSnail::Num(ref cur) => {
|
||||||
|
// cur.set(cur.get() + amt);
|
||||||
|
// }
|
||||||
|
// NumOrSnail::Snail(child) => {
|
||||||
|
// child.add_to_leftmost_leaf(amt);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn add_to_rightmost_leaf(&self, amt: usize) {
|
||||||
|
// match self {
|
||||||
|
// NumOrSnail::Num(ref cur) => {
|
||||||
|
// cur.set(cur.get() + amt);
|
||||||
|
// }
|
||||||
|
// NumOrSnail::Snail(child) => {
|
||||||
|
// child.add_to_rightmost_leaf(amt);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// impl Display for NumOrSnail {
|
||||||
|
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
// match self {
|
||||||
|
// NumOrSnail::Num(n) => write!(f, "{}", n.get()),
|
||||||
|
// NumOrSnail::Snail(snail) => write!(f, "{}", *snail),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -16,7 +16,8 @@ mod day14;
|
||||||
mod day15;
|
mod day15;
|
||||||
mod day16;
|
mod day16;
|
||||||
mod day17;
|
mod day17;
|
||||||
|
mod day18;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
day17::day17();
|
day18::day18();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue