advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git
commit 621e1341fae3ec25714d1719caa590af0d012a0a
parent c6a137276db40b5d7989702f7541aa95bfb29bfd
Author: Shimmy Xu <shimmy.xu@shimmy1996.com>
Date:   Sat, 18 Dec 2021 12:10:22 -0600

Add 2021 day 18

Diffstat:
A2021/day18/input.txt | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2021/day18/main.rs | 181+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 281 insertions(+), 0 deletions(-)
diff --git a/2021/day18/input.txt b/2021/day18/input.txt
@@ -0,0 +1,100 @@
+[[[[3,0],[0,0]],1],4]
+[[[[3,4],0],[7,7]],[1,6]]
+[[[[2,0],5],7],[[[3,1],[2,6]],[[0,8],6]]]
+[[[[5,5],0],1],[[[0,0],1],[[0,6],[0,9]]]]
+[[0,[0,[1,7]]],[3,[1,[7,6]]]]
+[[[9,[5,2]],[[5,2],[6,8]]],[[[7,0],7],[[2,3],[9,4]]]]
+[[[[3,8],7],[[0,7],[2,0]]],[0,[[2,9],0]]]
+[[[7,[2,2]],[3,4]],[6,7]]
+[8,[[[3,3],8],[[7,1],[6,7]]]]
+[[9,[9,8]],[[1,[9,1]],[2,5]]]
+[[[7,8],[[1,2],[2,6]]],[[9,7],[6,[7,0]]]]
+[[[3,3],[[5,6],5]],[[[2,8],1],9]]
+[[[2,[5,0]],[[9,9],[4,0]]],[0,5]]
+[[[9,3],[[9,4],[5,8]]],[[[3,2],[7,1]],[[3,8],1]]]
+[[3,2],[[6,[0,9]],[8,3]]]
+[[[5,7],[[7,4],[4,6]]],[[[9,8],3],3]]
+[[[4,[2,8]],9],[[[8,5],[9,7]],[[8,9],[2,6]]]]
+[[[1,[2,4]],6],[[8,[5,2]],[[0,7],[4,1]]]]
+[[[[4,3],6],[[6,4],[4,2]]],[[9,0],[[5,9],9]]]
+[[[[3,0],6],[4,[7,5]]],4]
+[[[[1,0],[7,1]],0],[[[8,5],8],2]]
+[[[[2,9],[4,1]],[[8,9],[3,3]]],[9,[[0,7],2]]]
+[[1,[4,[4,2]]],[[[3,5],[8,8]],2]]
+[[[8,[1,4]],[[6,5],5]],[[7,[4,7]],4]]
+[[[[0,5],2],[[9,2],0]],0]
+[[[[6,2],[2,4]],[0,[7,3]]],[9,[8,[5,9]]]]
+[[8,0],2]
+[[[[0,2],2],[[9,2],[8,1]]],[[[7,6],[5,3]],6]]
+[[[[8,7],[5,3]],[[3,0],8]],[[[8,4],[2,2]],[[8,1],2]]]
+[[[[1,5],[4,6]],[[4,0],[2,4]]],[[1,1],[[0,7],[7,3]]]]
+[[7,2],[[7,[6,7]],[8,5]]]
+[[[9,7],[[6,6],9]],8]
+[[4,2],[[[1,0],[9,1]],[[0,7],[8,0]]]]
+[[[[5,9],5],[8,9]],[[2,4],[[5,2],[8,3]]]]
+[[[[4,5],[7,0]],[4,5]],[[7,[6,4]],[[1,7],[6,3]]]]
+[[2,0],4]
+[[2,[[5,1],[2,1]]],[[5,[7,2]],[[2,3],[7,0]]]]
+[[4,[4,9]],[9,[6,8]]]
+[[[[6,1],[1,5]],[0,[4,0]]],[[[7,0],2],4]]
+[[[[3,3],[2,2]],[[2,4],2]],[[8,[1,1]],4]]
+[[[[1,5],8],[[9,4],[7,7]]],[[[8,7],[7,2]],[0,[7,3]]]]
+[9,[[7,[0,4]],4]]
+[4,[0,8]]
+[[[[2,6],1],[8,[8,4]]],[[8,2],[1,[8,4]]]]
+[[7,[8,[8,8]]],[4,1]]
+[[0,6],[[7,[5,9]],[[7,1],8]]]
+[4,6]
+[[[[3,2],[5,6]],[0,7]],[8,[7,[9,5]]]]
+[[[3,7],[4,5]],6]
+[[[0,[3,9]],[9,1]],6]
+[[[[7,3],8],[6,7]],[[1,0],[1,7]]]
+[[[5,[4,8]],2],[[[7,1],6],[[0,3],2]]]
+[[1,0],[[1,2],[[2,0],1]]]
+[[8,[[6,1],[7,1]]],0]
+[[9,[2,0]],[[7,[6,2]],4]]
+[[[9,[9,4]],[[4,8],3]],[[9,0],[[2,2],[0,6]]]]
+[[[7,5],[[2,9],6]],[[2,4],[[1,1],[8,2]]]]
+[[[1,[6,3]],[[2,2],[1,8]]],[[[7,3],[6,0]],[4,[7,6]]]]
+[6,5]
+[[3,[9,[4,4]]],[[6,9],[4,5]]]
+[[[4,[1,8]],[[4,0],6]],[[[9,0],[8,3]],[[8,6],[3,2]]]]
+[[[8,[1,2]],[[3,9],6]],[[3,0],1]]
+[[1,[2,[4,0]]],6]
+[0,[[[1,3],[9,1]],[[3,8],[9,4]]]]
+[2,[2,[[2,7],[7,8]]]]
+[[[3,0],[[4,6],2]],[9,2]]
+[[[5,[2,2]],[[2,7],[9,9]]],[[3,[4,4]],[8,[9,8]]]]
+[[[[7,5],[7,9]],[[8,5],6]],[[1,[8,4]],[8,2]]]
+[[[6,4],[5,5]],[[[8,1],5],[[6,4],[6,9]]]]
+[[[[8,9],0],[[4,6],7]],[[[3,9],[6,4]],[8,[7,4]]]]
+[4,[[7,7],4]]
+[[[[4,9],[1,2]],[8,[4,7]]],[[8,[4,8]],[0,[5,4]]]]
+[1,[7,9]]
+[[[5,[2,0]],[[4,3],[6,8]]],[9,9]]
+[[[[3,9],9],[4,3]],[1,[3,[8,1]]]]
+[[[[8,7],[6,1]],[3,9]],[5,[[8,0],4]]]
+[[[[8,2],[4,6]],[6,[9,9]]],[1,[[7,7],4]]]
+[[7,5],[[5,0],[0,3]]]
+[[[6,0],[9,1]],[[[4,3],[5,0]],[[9,5],[0,0]]]]
+[8,[[3,6],3]]
+[[[[9,3],7],[1,3]],[[[6,4],[8,4]],[1,5]]]
+[[[[3,8],2],[5,4]],[[[1,8],5],[2,[2,7]]]]
+[[2,9],[6,[0,2]]]
+[[2,[7,9]],[[4,1],[[9,2],[0,7]]]]
+[[0,[6,4]],[[9,2],[0,[0,7]]]]
+[[[[7,2],[8,6]],[6,2]],[[[1,6],[2,2]],1]]
+[[1,6],[[[4,3],[8,2]],[3,[9,4]]]]
+[[9,[7,3]],[[[7,0],4],[[1,7],[2,2]]]]
+[[7,[5,[9,8]]],[[[7,5],[7,6]],[7,[9,8]]]]
+[[[[6,1],[4,3]],4],[[[5,9],4],2]]
+[[[[5,1],[2,5]],0],[[7,[5,7]],[[4,4],9]]]
+[9,2]
+[4,[[[6,6],5],7]]
+[[8,[[7,3],[0,7]]],8]
+[[[3,4],[[2,3],0]],[[[9,6],[1,1]],[4,[0,4]]]]
+[[[[3,3],[2,3]],[2,5]],[[4,[2,7]],3]]
+[[[8,[0,3]],2],[4,4]]
+[[[3,5],[[2,1],[3,4]]],[[0,3],4]]
+[[[[4,1],4],2],[[[3,7],2],[[8,1],3]]]
+[[[[0,6],[7,3]],[5,[3,9]]],[7,[[4,1],8]]]
diff --git a/2021/day18/main.rs b/2021/day18/main.rs
@@ -0,0 +1,181 @@
+use std::collections::VecDeque;
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+enum Pos {
+    Left,
+    Right,
+}
+
+impl Pos {
+    fn calc_mult(pos_stack: &VecDeque<Pos>) -> u64 {
+        pos_stack
+            .iter()
+            .map(|p| match p {
+                Self::Left => 3,
+                Self::Right => 2,
+            })
+            .product()
+    }
+}
+
+#[derive(Debug, Clone, Copy)]
+struct Snailfish {
+    value: u32,
+    depth: i32,
+    pos: Pos,
+}
+
+impl Snailfish {
+    fn parse(s: &str) -> Vec<Snailfish> {
+        let mut res = Vec::new();
+        let mut prev_char = None;
+        let mut curr_depth = 0;
+        for c in s.chars() {
+            match (prev_char, c.to_digit(10)) {
+                (Some('['), Some(v)) => res.push(Snailfish {
+                    value: v,
+                    depth: curr_depth,
+                    pos: Pos::Left,
+                }),
+                (Some(','), Some(v)) => res.push(Snailfish {
+                    value: v,
+                    depth: curr_depth,
+                    pos: Pos::Right,
+                }),
+                (_, None) => match c {
+                    '[' => curr_depth += 1,
+                    ']' => curr_depth -= 1,
+                    _ => (),
+                },
+                _ => (),
+            }
+            prev_char = Some(c);
+        }
+        res
+    }
+
+    fn sum(a: &Vec<Snailfish>, b: &Vec<Snailfish>) -> Vec<Snailfish> {
+        let mut sum = a
+            .iter()
+            .chain(b.iter())
+            .map(|&v| v)
+            .collect::<Vec<Snailfish>>();
+        for v in sum.iter_mut() {
+            v.depth += 1;
+        }
+        Self::reduce(sum)
+    }
+
+    fn reduce(mut val: Vec<Snailfish>) -> Vec<Snailfish> {
+        loop {
+            let mut new_val = Vec::<Snailfish>::new();
+            let mut reduced = false;
+            // explode
+            let mut carry = 0;
+            for mut v in val.into_iter() {
+                if !reduced && v.pos == Pos::Right && v.depth > 4 {
+                    reduced = true;
+                    let left = new_val.pop().unwrap();
+                    let mut pair_pos = Pos::Left;
+                    if let Some(last) = new_val.last_mut() {
+                        last.value += left.value;
+                        if last.pos == Pos::Left && v.depth - 1 == last.depth {
+                            pair_pos = Pos::Right;
+                        }
+                    }
+                    new_val.push(Snailfish {
+                        value: 0,
+                        depth: v.depth - 1,
+                        pos: pair_pos,
+                    });
+                    carry = v.value;
+                } else {
+                    v.value += carry;
+                    carry = 0;
+                    new_val.push(v);
+                }
+            }
+            val = new_val;
+            if reduced {
+                continue;
+            }
+            // split
+            // need to be a separate loop as first rule only triggers on Right elem
+            let mut new_val = Vec::<Snailfish>::new();
+            for v in val.into_iter() {
+                if !reduced && v.value >= 10 {
+                    reduced = true;
+                    new_val.push(Snailfish {
+                        value: v.value / 2,
+                        depth: v.depth + 1,
+                        pos: Pos::Left,
+                    });
+                    new_val.push(Snailfish {
+                        value: (v.value + 1) / 2,
+                        depth: v.depth + 1,
+                        pos: Pos::Right,
+                    });
+                } else {
+                    new_val.push(v);
+                }
+            }
+            val = new_val;
+            if !reduced {
+                break;
+            }
+        }
+        val
+    }
+
+    fn magnitude(val: &Vec<Snailfish>) -> u64 {
+        let mut res = 0;
+        let mut pos = std::collections::VecDeque::<Pos>::new();
+        for v in val {
+            while pos.len() < v.depth as usize {
+                pos.push_back(Pos::Left);
+            }
+            *pos.back_mut().unwrap() = v.pos;
+            res += v.value as u64 * Pos::calc_mult(&pos);
+            while let Some(&Pos::Right) = pos.back() {
+                pos.pop_back();
+            }
+            if let Some(back) = pos.back_mut() {
+                *back = Pos::Right;
+            }
+        }
+        res
+    }
+}
+
+fn main() {
+    let input = std::fs::read_to_string("input.txt")
+        .unwrap()
+        .trim()
+        .split('\n')
+        .map(|s| Snailfish::parse(s))
+        .collect::<Vec<Vec<_>>>();
+    // 4207
+    println!("Part 1: {}", part_1(&input));
+    // 4635
+    println!("Part 2: {}", part_2(&input));
+}
+
+fn part_1(input: &Vec<Vec<Snailfish>>) -> u64 {
+    let sum = input
+        .clone()
+        .into_iter()
+        .reduce(|a, b| Snailfish::sum(&a, &b))
+        .unwrap();
+    Snailfish::magnitude(&sum)
+}
+
+fn part_2(input: &Vec<Vec<Snailfish>>) -> u64 {
+    let mut max_magnitude = 0;
+    for a in input.iter() {
+        for b in input.iter() {
+            max_magnitude = max_magnitude.max(Snailfish::magnitude(&Snailfish::sum(a, b)));
+        }
+    }
+
+    max_magnitude
+}