2021 Day 18

This commit is contained in:
Akumatic 2021-12-18 21:15:08 +01:00
parent 9a6c9f4a00
commit ddceb28761
8 changed files with 519 additions and 1 deletions

211
2021/18/README.md Normal file
View File

@ -0,0 +1,211 @@
# 2021 Day 18: Snailfish
Copyright (c) Eric Wastl
#### [Direct Link](https://adventofcode.com/2021/day/18)
## Part 1
You descend into the ocean trench and encounter some [snailfish](https://en.wikipedia.org/wiki/Snailfish). They say they saw the sleigh keys! They'll even tell you which direction the keys went if you help one of the smaller snailfish with his **math homework**.
Snailfish numbers aren't like regular numbers. Instead, every snailfish number is a **pair** - an ordered list of two elements. Each element of the pair can be either a regular number or another pair.
Pairs are written as `[x,y]`, where `x` and `y` are the elements within the pair. Here are some example snailfish numbers, one snailfish number per line:
```
[1,2]
[[1,2],3]
[9,[8,7]]
[[1,9],[8,5]]
[[[[1,2],[3,4]],[[5,6],[7,8]]],9]
[[[9,[3,8]],[[0,9],6]],[[[3,7],[4,9]],3]]
[[[[1,3],[5,3]],[[1,3],[8,7]]],[[[4,9],[6,9]],[[8,2],[7,3]]]]
```
This snailfish homework is about **addition**. To add two snailfish numbers, form a pair from the left and right parameters of the addition operator. For example, `[1,2]` + `[[3,4],5]` becomes `[[1,2],[[3,4],5]]`.
There's only one problem: **snailfish numbers must always be reduced**, and the process of adding two snailfish numbers can result in snailfish numbers that need to be reduced.
To **reduce a snailfish number**, you must repeatedly do the first action in this list that applies to the snailfish number:
- If any pair is **nested inside four pairs**, the leftmost such pair **explodes**.
- If any regular number is **10 or greater**, the leftmost such regular number **splits**.
Once no action in the above list applies, the snailfish number is reduced.
During reduction, at most one action applies, after which the process returns to the top of the list of actions. For example, if **split** produces a pair that meets the **explode** criteria, that pair **explodes** before other splits occur.
To **explode** a pair, the pair's left value is added to the first regular number to the left of the exploding pair (if any), and the pair's right value is added to the first regular number to the right of the exploding pair (if any). Exploding pairs will always consist of two regular numbers. Then, the entire exploding pair is replaced with the regular number `0`.
Here are some examples of a single explode action:
- `[[[[[9,8],1],2],3],4]` becomes `[[[[0,9],2],3],4]` (the `9` has no regular number to its left, so it is not added to any regular number).
- `[7,[6,[5,[4,[3,2]]]]]` becomes `[7,[6,[5,[7,0]]]]` (the `2` has no regular number to its right, and so it is not added to any regular number).
- `[[6,[5,[4,[3,2]]]],1]` becomes `[[6,[5,[7,0]]],3]`.
- `[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]` becomes `[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]` (the pair `[3,2]` is unaffected because the pair `[7,3]` is further to the left; `[3,2]` would explode on the next action).
- `[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]` becomes [[3,[2,[8,0]]],[9,[5,[7,0]]]].
To **split** a regular number, replace it with a pair; the left element of the pair should be the regular number divided by two and rounded **down**, while the right element of the pair should be the regular number divided by two and rounded **up**. For example, `10` becomes `[5,5]`, `11` becomes `[5,6]`, `12` becomes `[6,6]`, and so on.
Here is the process of finding the reduced result of `[[[[4,3],4],4],[7,[[8,4],9]]]` + `[1,1]`:
```
after addition: [[[[[4,3],4],4],[7,[[8,4],9]]],[1,1]]
after explode: [[[[0,7],4],[7,[[8,4],9]]],[1,1]]
after explode: [[[[0,7],4],[15,[0,13]]],[1,1]]
after split: [[[[0,7],4],[[7,8],[0,13]]],[1,1]]
after split: [[[[0,7],4],[[7,8],[0,[6,7]]]],[1,1]]
after explode: [[[[0,7],4],[[7,8],[6,0]]],[8,1]]
```
Once no reduce actions apply, the snailfish number that remains is the actual result of the addition operation: `[[[[0,7],4],[[7,8],[6,0]]],[8,1]]`.
The homework assignment involves adding up a **list of snailfish numbers** (your puzzle input). The snailfish numbers are each listed on a separate line. Add the first snailfish number and the second, then add that result and the third, then add that result and the fourth, and so on until all numbers in the list have been used once.
For example, the final sum of this list is `[[[[1,1],[2,2]],[3,3]],[4,4]]`:
```
[1,1]
[2,2]
[3,3]
[4,4]
```
The final sum of this list is `[[[[3,0],[5,3]],[4,4]],[5,5]]`:
```
[1,1]
[2,2]
[3,3]
[4,4]
[5,5]
```
The final sum of this list is `[[[[5,0],[7,4]],[5,5]],[6,6]]`:
```
[1,1]
[2,2]
[3,3]
[4,4]
[5,5]
[6,6]
```
Here's a slightly larger example:
```
[[[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]]
```
The final sum `[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]` is found after adding up the above snailfish numbers:
```
[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]
+ [7,[[[3,7],[4,3]],[[6,3],[8,8]]]]
= [[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]
[[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]
+ [[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]
= [[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]
[[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]
+ [[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]
= [[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]
[[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]
+ [7,[5,[[3,8],[1,4]]]]
= [[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]
[[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]
+ [[2,[2,2]],[8,[8,1]]]
= [[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]
[[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]
+ [2,9]
= [[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]
[[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]
+ [1,[[[9,3],9],[[9,0],[0,7]]]]
= [[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]
[[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]
+ [[[5,[7,4]],7],1]
= [[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]
[[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]
+ [[[[4,2],2],6],[8,7]]
= [[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]
```
To check whether it's the right answer, the snailfish teacher only checks the **magnitude** of the final sum. The magnitude of a pair is 3 times the magnitude of its left element plus 2 times the magnitude of its right element. The magnitude of a regular number is just that number.
For example, the magnitude of `[9,1]` is `3*9 + 2*1 = 29`; the magnitude of `[1,9]` is `3*1 + 2*9 = 21`. Magnitude calculations are recursive: the magnitude of `[[9,1],[1,9]]` is `3*29 + 2*21 = 129`.
Here are a few more magnitude examples:
- `[[1,2],[[3,4],5]]` becomes **143**.
- `[[[[0,7],4],[[7,8],[6,0]]],[8,1]]` becomes **1384**.
- `[[[[1,1],[2,2]],[3,3]],[4,4]]` becomes **445**.
- `[[[[3,0],[5,3]],[4,4]],[5,5]]` becomes **791**.
- `[[[[5,0],[7,4]],[5,5]],[6,6]]` becomes **1137**.
- `[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]` becomes **3488**.
So, given this example homework assignment:
```
[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
[[[5,[2,8]],4],[5,[[9,9],0]]]
[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
[[[[5,4],[7,7]],8],[[8,3],8]]
[[9,3],[[9,9],[6,[4,9]]]]
[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]
```
The final sum is:
```
[[[[6,6],[7,6]],[[7,7],[7,0]]],[[[7,7],[7,7]],[[7,8],[9,9]]]]
```
The magnitude of this final sum is **`4140`**.
Add up all of the snailfish numbers from the homework assignment in the order they appear. **What is the magnitude of the final sum?**
## Part 2
You notice a second question on the back of the homework assignment:
What is the largest magnitude you can get from adding only two of the snailfish numbers?
Note that snailfish addition is not [commutative](https://en.wikipedia.org/wiki/Commutative_property) - that is, `x + y` and `y + x` can produce different results.
Again considering the last example homework assignment above:
```
[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
[[[5,[2,8]],4],[5,[[9,9],0]]]
[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
[[[[5,4],[7,7]],8],[[8,3],8]]
[[9,3],[[9,9],[6,[4,9]]]]
[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]
```
The largest magnitude of the sum of any two snailfish numbers in this list is **`3993`**. This is the magnitude of `[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]` + `[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]`, which reduces to `[[[[7,8],[6,6]],[[6,0],[7,7]]],[[[7,8],[8,8]],[[7,9],[0,6]]]]`.
**What is the largest magnitude of any sum of two different snailfish numbers from the homework assignment?**

144
2021/18/code.py Normal file
View File

@ -0,0 +1,144 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2021 Akumatic
#
# https://adventofcode.com/2021/day/18
import math
class Node:
def __init__(self, left: "Node" = None, right: "Node" = None,
value: int = None, parent: "Node" = None, depth: int = 1):
self.left = left
self.right = right
self.value = value
self.parent = parent
self.depth = depth
def __str__(self) -> str:
return str(self.value) if self.value is not None else f"[{self.left},{self.right}]"
def explode(self) -> bool:
if self.depth < 5:
tmp = False
if self.left.value is None:
tmp = self.left.explode()
if tmp:
return True
if self.right.value is None:
tmp = self.right.explode()
return tmp
elif self.depth == 5:
assert self.left.value is not None and self.right.value is not None
left = self._find_next_node_with_value(left = True)
right = self._find_next_node_with_value(left = False)
if left:
left.value += self.left.value
if right:
right.value += self.right.value
self.left, self.right, self.value = None, None, 0
return True
def split(self) -> bool:
if self.value is None:
tmp = False
tmp = self.left.split()
if tmp:
return True
tmp = self.right.split()
return tmp
if self.value < 10:
return False
val = self.value / 2
self.value = None
self.left = Node(value=math.floor(val), parent=self, depth=self.depth + 1)
self.right = Node(value=math.ceil(val), parent=self, depth=self.depth + 1)
return True
def set_parent(self, parent: "Node") -> None:
self.parent = parent
self.depth = parent.depth + 1
if self.value is None:
self.left.set_parent(self)
self.right.set_parent(self)
def _find_next_node_with_value(self, left: bool) -> "Node":
no_parent = True
node = self
while node.parent is not None:
if left and node.parent.right == node or not left and node.parent.left == node:
node = node.parent.left if left else node.parent.right
no_parent = False
break
else:
node = node.parent
if no_parent:
return None
else:
while left and node.right is not None or not left and node.left is not None:
node = node.right if left else node.left
return node
def read_file(filename: str = "input.txt") -> list:
with open(f"{__file__.rstrip('code.py')}{filename}", "r") as f:
return [eval(line) for line in f.read().strip().split("\n")]
def parse_node(node: list, depth: int = 1) -> Node:
a = Node(value=node[0], depth=depth) if isinstance(node[0], int) else parse_node(node[0], depth = depth + 1)
b = Node(value=node[1], depth=depth) if isinstance(node[1], int) else parse_node(node[1], depth = depth + 1)
node = Node(left=a, right=b, depth=depth)
a.set_parent(node)
b.set_parent(node)
return node
def reduce(node: Node) -> None:
repeat = True
while repeat:
repeat = False
explosion_result = node.explode()
if explosion_result:
repeat = True
continue
repeat = node.split()
def add(a: Node, b: Node) -> Node:
node = Node(left=a, right=b)
a.set_parent(node)
b.set_parent(node)
reduce(node)
return node
def sum_nodes(nodes: list) -> list:
node = parse_node(nodes[0])
for i in range(1, len(nodes)):
node = add(node, parse_node(nodes[i]))
return node
def get_magnitude(node: Node) -> int:
if node.value is not None:
return node.value
return 3 * get_magnitude(node.left) + 2 * get_magnitude(node.right)
def part1(vals: list) -> int:
tree = sum_nodes(vals)
return get_magnitude(tree)
def part2(vals: list) -> int:
max_mag = 0
nodes = [parse_node(node) for node in vals]
for i in range(len(vals)):
for j in range(len(vals)):
if i == j:
continue
a, b = parse_node(vals[i]), parse_node(vals[j])
c, d = parse_node(vals[i]), parse_node(vals[j])
max_mag = max(max_mag, get_magnitude(add(a, b)), get_magnitude(add(c, d)))
return max_mag
if __name__ == "__main__":
vals = read_file()
print(f"Part 1: {part1(vals)}")
print(f"Part 2: {part2(vals)}")

100
2021/18/input.txt Normal file
View File

@ -0,0 +1,100 @@
[[[0,[4,4]],6],[[[7,6],6],[[5,3],[3,2]]]]
[[[[4,6],[1,7]],[5,8]],[[9,7],[9,6]]]
[[[2,[7,1]],[[8,2],[9,3]]],3]
[[[[2,1],6],2],4]
[[[[0,3],0],6],[[9,[0,8]],[[2,1],[0,2]]]]
[[[5,1],[[0,5],1]],[[[9,9],[8,7]],7]]
[[[[0,2],8],8],[0,[7,[2,7]]]]
[[[[3,8],[6,4]],[[2,0],2]],3]
[[[[1,5],3],[[5,3],[5,4]]],[[0,1],[[1,2],8]]]
[[[1,1],[[9,3],9]],[[9,[6,5]],[2,6]]]
[[[9,3],[6,[1,5]]],[[3,8],[[4,6],[8,0]]]]
[[3,[6,7]],[[3,0],[5,[3,4]]]]
[1,[2,[[4,1],[2,3]]]]
[[6,[7,8]],[[0,[0,3]],[6,7]]]
[[8,[[0,0],[9,3]]],[[2,6],[[9,1],[4,9]]]]
[[3,0],[[8,[7,1]],4]]
[[[1,0],[[9,7],[7,8]]],[[[0,0],5],[[4,9],4]]]
[[[[4,2],7],[[4,0],0]],[[[5,4],[6,7]],[0,[1,2]]]]
[[[4,[4,3]],[[1,4],[1,1]]],6]
[[[0,[5,9]],[[7,4],2]],[[9,1],[4,7]]]
[[[[5,5],[7,0]],[8,[5,3]]],[[0,[0,2]],[[1,3],[5,8]]]]
[[9,[[9,9],2]],[[9,6],[[4,7],5]]]
[[[[8,7],[5,3]],9],[3,[6,9]]]
[[3,[0,3]],[2,6]]
[[[2,[7,0]],[6,6]],[[7,0],[[3,8],[8,5]]]]
[[[2,6],[2,7]],[[3,6],[0,[9,5]]]]
[[[5,4],1],[5,[[4,9],5]]]
[[[6,3],6],[[[6,0],0],[[4,0],7]]]
[[[[4,1],2],[3,[9,0]]],[0,8]]
[[[2,[3,9]],[[8,3],8]],[[1,[2,2]],[8,[6,4]]]]
[[[[4,3],[5,2]],0],[9,[5,[7,5]]]]
[[[3,2],5],[[[6,3],9],[[2,0],[6,7]]]]
[[[3,9],[[0,6],[0,7]]],[6,[3,2]]]
[0,0]
[[[[0,3],9],[8,[3,9]]],[[0,2],[[0,1],[3,7]]]]
[[0,[4,[3,0]]],[[7,9],[5,[8,7]]]]
[[2,9],[[0,[2,2]],1]]
[[[[5,4],[1,7]],6],[2,[[5,3],[7,7]]]]
[[[[0,4],4],[[6,6],[1,4]]],4]
[[[[4,8],5],[[6,4],[2,3]]],[9,[[8,6],[4,0]]]]
[[1,[6,[1,9]]],[3,[[4,2],[1,8]]]]
[[[[3,7],[5,9]],[[3,8],[3,3]]],[[[7,8],3],[7,3]]]
[[[[0,4],5],[4,[9,0]]],[3,[[4,1],6]]]
[[[7,[2,1]],[[1,9],1]],[[[3,4],[8,6]],6]]
[[[4,1],[5,[8,2]]],[[[1,6],9],[[4,4],2]]]
[[[7,[6,4]],[[0,1],4]],[[5,2],[[9,5],[9,3]]]]
[[[4,2],[1,8]],2]
[[[1,6],5],[8,[2,[2,3]]]]
[[[[0,2],[5,0]],[7,[0,0]]],[[6,[5,9]],5]]
[[[7,6],[9,[2,4]]],[[5,[2,6]],2]]
[[[6,2],4],[[2,9],[[3,0],[4,3]]]]
[[8,[[6,4],[0,2]]],1]
[[[4,1],[7,5]],[9,[[2,4],4]]]
[[[[4,8],[7,5]],[1,[8,5]]],[[3,5],[[9,9],[4,2]]]]
[[[7,[8,4]],[4,[5,8]]],5]
[[7,9],[2,[[9,1],[7,1]]]]
[3,[[[5,8],[4,8]],[5,4]]]
[[[0,[5,5]],[[5,4],[5,4]]],[[9,6],[[9,4],[6,5]]]]
[[7,2],[1,[8,[1,7]]]]
[2,[9,[2,[2,3]]]]
[[[3,[5,1]],[8,[6,4]]],[[2,8],[[2,2],8]]]
[[[7,3],[0,4]],[[4,0],[6,[3,4]]]]
[[4,[2,[2,8]]],[4,[[7,1],9]]]
[[8,[[6,1],2]],[1,[[1,5],9]]]
[[0,[2,[9,4]]],[[[7,4],7],8]]
[[[2,[7,0]],5],[3,[4,4]]]
[[7,[4,[6,0]]],[[4,7],[[3,7],5]]]
[[2,[[8,0],[6,1]]],[[6,[6,1]],[3,9]]]
[[9,0],[[[3,7],0],[[5,8],4]]]
[6,[[[5,8],8],[3,[4,1]]]]
[[8,[[9,3],[8,4]]],[4,[8,2]]]
[[[[8,0],8],[3,7]],[[7,[4,3]],0]]
[[[7,[2,6]],[8,0]],[4,[[1,3],[4,1]]]]
[1,[[[4,9],[4,9]],[[7,0],[6,6]]]]
[9,4]
[[6,7],4]
[[2,[5,2]],[[2,4],[[4,6],[5,5]]]]
[[[5,2],[[5,5],[8,1]]],[[9,[1,6]],3]]
[[[[4,3],1],[8,9]],6]
[[[[3,2],[4,5]],4],[[[4,3],[0,0]],[[3,0],1]]]
[[6,7],[[8,5],[[7,2],4]]]
[[[[8,1],[5,8]],7],[[[5,2],[4,3]],1]]
[[2,[[4,9],5]],[1,1]]
[[9,1],[[[0,8],[1,8]],7]]
[[9,3],[6,4]]
[[8,[4,2]],[[7,[7,4]],[[0,9],[6,1]]]]
[[[[0,5],7],[[7,7],2]],[[2,[5,8]],[9,6]]]
[[[2,1],[7,[1,3]]],[[2,[7,1]],0]]
[[[8,[8,4]],[2,[4,3]]],[[2,[5,6]],[[2,0],[7,3]]]]
[[4,[[4,3],[5,2]]],[1,3]]
[[5,[5,0]],9]
[[[2,[7,6]],[1,8]],[[[5,2],2],0]]
[[2,[2,3]],[[9,8],[[0,1],[3,5]]]]
[[7,[[3,7],3]],[[[7,6],[4,8]],[[1,7],[8,6]]]]
[[[0,0],[[6,1],5]],[5,[5,4]]]
[[2,3],[4,[3,5]]]
[[8,[7,7]],[8,[4,[8,1]]]]
[[[[4,0],3],[[0,0],[0,0]]],[[[6,0],4],[[1,7],0]]]
[[[[6,4],[3,1]],[[2,8],[1,2]]],[4,[[6,5],4]]]
[[[[5,3],7],[4,[2,6]]],[[6,[4,5]],[1,[9,0]]]]

2
2021/18/solution.txt Normal file
View File

@ -0,0 +1,2 @@
Part 1: 4202
Part 2: 4779

41
2021/18/test_code.py Normal file
View File

@ -0,0 +1,41 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2021 Akumatic
from code import *
def test_explode(a, b):
tmp = parse_node(a)
tmp.explode()
return str(tmp) == str(parse_node(b))
def test():
vals = read_file("test_input_2.txt")
assert str(parse_node([1,2])) == "[1,2]"
assert str(add(parse_node([1,2]), parse_node([[3,4],5]))) == "[[1,2],[[3,4],5]]"
assert test_explode([[[[[9,8],1],2],3],4], [[[[0,9],2],3],4])
assert test_explode([7,[6,[5,[4,[3,2]]]]], [7,[6,[5,[7,0]]]])
assert test_explode([[6,[5,[4,[3,2]]]],1], [[6,[5,[7,0]]],3])
assert test_explode([[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]], [[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]])
assert test_explode([[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]], [[3,[2,[8,0]]],[9,[5,[7,0]]]])
print("Passed explosion test")
assert str(add(parse_node([[[[4,3],4],4],[7,[[8,4],9]]]), parse_node([1,1]))) == str(parse_node([[[[0,7],4],[[7,8],[6,0]]],[8,1]]))
print("Passed reduction test")
assert str(sum_nodes([[1,1], [2,2], [3,3], [4,4]])) == "[[[[1,1],[2,2]],[3,3]],[4,4]]"
assert str(sum_nodes([[1,1], [2,2], [3,3], [4,4], [5,5]])) == "[[[[3,0],[5,3]],[4,4]],[5,5]]"
assert str(sum_nodes([[1,1], [2,2], [3,3], [4,4], [5,5], [6,6]])) == "[[[[5,0],[7,4]],[5,5]],[6,6]]"
assert str(sum_nodes(read_file("test_input_1.txt"))) == "[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]"
assert str(sum_nodes(vals)) == "[[[[6,6],[7,6]],[[7,7],[7,0]]],[[[7,7],[7,7]],[[7,8],[9,9]]]]"
print("Passed summing nodes test")
assert get_magnitude(parse_node([[1,2],[[3,4],5]])) == 143.
assert get_magnitude(parse_node([[[[0,7],4],[[7,8],[6,0]]],[8,1]])) == 1384.
assert get_magnitude(parse_node([[[[1,1],[2,2]],[3,3]],[4,4]])) == 445.
assert get_magnitude(parse_node([[[[3,0],[5,3]],[4,4]],[5,5]])) == 791.
assert get_magnitude(parse_node([[[[5,0],[7,4]],[5,5]],[6,6]])) == 1137.
assert get_magnitude(parse_node([[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]])) == 3488.
assert part1(vals) == 4140
print("Passed magnitude test")
assert part2(vals) == 3993
print("Passed Part 2")
if __name__ == "__main__":
test()

10
2021/18/test_input_1.txt Normal file
View File

@ -0,0 +1,10 @@
[[[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]]

10
2021/18/test_input_2.txt Normal file
View File

@ -0,0 +1,10 @@
[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
[[[5,[2,8]],4],[5,[[9,9],0]]]
[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
[[[[5,4],[7,7]],8],[[8,3],8]]
[[9,3],[[9,9],[6,[4,9]]]]
[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]

View File

@ -32,7 +32,7 @@ Collect stars by solving puzzles. Two puzzles will be made available on each day
| 15 | :white_check_mark: | :white_check_mark: | [Solution](15/code.py) | [Day 15](https://adventofcode.com/2021/day/15) |
| 16 | :white_check_mark: | :white_check_mark: | [Solution](16/code.py) | [Day 16](https://adventofcode.com/2021/day/16) |
| 17 | :white_check_mark: | :white_check_mark: | [Solution](17/code.py) | [Day 17](https://adventofcode.com/2021/day/17) |
| 18 | | | | |
| 18 | :white_check_mark: | :white_check_mark: | [Solution](18/code.py) | [Day 18](https://adventofcode.com/2021/day/18) |
| 19 | | | | |
| 20 | | | | |
| 21 | | | | |