# Day18
## Untitled
<!-- livebook:{"livebook_object":"cell_input","name":"input","type":"textarea","value":"[[[[6,3],7],0],[[7,0],0]]\n[[[4,7],[6,[6,5]]],[4,[[6,5],[9,1]]]]\n[[[[3,7],[6,9]],[3,[4,1]]],8]\n[[[0,[2,0]],3],2]\n[[[[1,3],4],9],[[[1,8],[9,3]],[0,7]]]\n[[[5,9],1],[[[4,8],[4,8]],[[9,7],[3,6]]]]\n[[[0,7],4],[[[0,4],2],[4,2]]]\n[[5,1],[2,5]]\n[[[[4,8],[8,3]],[6,[2,3]]],[[6,0],[1,3]]]\n[[[[1,7],[8,1]],[2,[3,4]]],[[7,[8,7]],[[8,6],5]]]\n[[9,[[8,9],[0,6]]],[[[8,4],5],[0,[1,7]]]]\n[[[[9,8],[6,9]],[[3,5],[6,2]]],[[[7,8],5],8]]\n[[[[7,1],8],[0,2]],[3,5]]\n[[[1,9],3],[8,[8,[7,8]]]]\n[[[9,[8,5]],[1,[9,0]]],5]\n[9,[[[1,1],8],[[3,5],9]]]\n[[[1,[7,8]],2],[8,0]]\n[7,[8,[[6,1],[7,9]]]]\n[[7,[[4,7],7]],[[8,[5,2]],2]]\n[[[[1,7],[9,0]],3],[8,[4,[2,0]]]]\n[[4,3],[[9,[7,7]],7]]\n[[[[9,5],3],[[8,5],5]],5]\n[[[[4,9],2],[[5,6],[9,0]]],[[2,[2,2]],1]]\n[[[[7,9],[6,0]],[1,[5,8]]],[8,8]]\n[[[[0,5],2],[4,[5,7]]],[8,[[8,1],[6,7]]]]\n[9,[7,[[3,7],[6,4]]]]\n[[[[5,3],[5,2]],[[5,0],0]],[[[4,6],[6,4]],[8,8]]]\n[1,[[8,0],0]]\n[[3,[7,9]],[[[1,2],[1,6]],[[9,2],[2,8]]]]\n[[[2,8],[3,[8,3]]],[3,[[9,8],[5,6]]]]\n[[[[2,0],3],[5,1]],[[[2,9],7],[[0,4],[1,4]]]]\n[[3,[[0,0],[9,0]]],[[6,[0,5]],[[5,4],[5,2]]]]\n[[8,[[9,4],[6,8]]],[3,[[8,1],4]]]\n[[[[4,1],[5,1]],[4,[9,1]]],4]\n[2,[[[0,5],[8,7]],[[6,1],[1,0]]]]\n[7,[8,8]]\n[[[[7,3],5],9],[[[5,9],[3,5]],[[9,4],8]]]\n[[[[4,2],[6,1]],[[6,6],7]],[2,2]]\n[[[1,1],4],[[[4,8],0],[[6,7],7]]]\n[[[[5,9],[0,1]],[9,7]],2]\n[[[[6,4],[5,5]],[[2,8],0]],9]\n[[7,[4,9]],[5,[[0,2],2]]]\n[[2,[9,9]],[[8,5],8]]\n[3,[8,[6,[2,8]]]]\n[[[0,1],[[8,5],[8,9]]],0]\n[[[[1,8],[1,4]],8],[[6,8],[8,[5,7]]]]\n[[[[7,1],[2,0]],[2,4]],[[[3,7],[2,2]],1]]\n[[[[0,3],[8,0]],[2,6]],[[6,2],[0,4]]]\n[[[7,1],[[6,8],[3,2]]],[[8,[3,2]],[1,[0,1]]]]\n[[[8,[5,7]],4],[[1,[1,9]],[[4,9],[4,2]]]]\n[[[8,5],3],[[9,8],[[4,4],[7,2]]]]\n[[5,[5,[8,7]]],[[8,0],[[6,3],6]]]\n[[[8,4],[[5,2],[7,0]]],[[[9,7],[8,9]],7]]\n[[5,[3,[3,0]]],5]\n[[[[0,1],[0,0]],[4,[3,7]]],[8,0]]\n[5,[[[8,3],8],5]]\n[[[5,[0,6]],4],[4,[3,[6,3]]]]\n[[[[4,1],[3,5]],[[5,0],7]],[[[7,9],[8,8]],[[8,0],[5,8]]]]\n[[[7,[6,6]],[[6,2],2]],8]\n[1,[4,[[2,9],[3,8]]]]\n[[[9,[5,4]],[[2,5],7]],[[4,2],9]]\n[[9,1],[[0,7],[[4,1],[5,6]]]]\n[[[7,[8,6]],[[4,5],1]],[[[2,1],[6,3]],[4,[0,3]]]]\n[[0,[2,[7,5]]],[[[5,0],5],3]]\n[[[0,[4,1]],7],[[[3,7],5],[[5,9],7]]]\n[[4,[[1,3],1]],[[9,6],[[6,2],3]]]\n[3,[[[8,5],6],4]]\n[[2,7],[[[3,9],3],[[2,1],2]]]\n[[4,[5,[9,9]]],[[[3,0],[4,1]],[[6,4],9]]]\n[[[7,9],[[5,7],[2,1]]],[[[1,4],6],[3,3]]]\n[[[[4,0],3],[3,[6,3]]],[[[6,2],4],5]]\n[[9,[[2,4],3]],[[9,[1,0]],[[5,8],[7,1]]]]\n[8,[1,5]]\n[[[5,5],3],[[[8,9],3],4]]\n[[1,[[8,8],[7,4]]],[[[9,1],[9,6]],[7,8]]]\n[[[7,2],[[0,1],5]],7]\n[[9,3],[7,[1,[9,2]]]]\n[[[[8,2],[8,0]],[[7,1],6]],[0,[[9,4],1]]]\n[[[[1,3],2],[6,[0,0]]],[[[7,8],[4,3]],[[9,4],1]]]\n[[[[2,1],[7,1]],[[5,4],[9,2]]],[[3,0],0]]\n[[[8,6],[[2,1],[9,1]]],[[3,[1,8]],[3,3]]]\n[[[[6,2],[3,6]],3],[5,9]]\n[[[[7,6],7],[[4,2],1]],[[0,4],[[9,8],6]]]\n[[8,[[7,6],[8,5]]],[[2,7],[[7,0],[0,0]]]]\n[[[0,[0,0]],4],[[[6,1],8],[[5,9],[6,5]]]]\n[[[8,[9,9]],9],[[3,[2,8]],[[9,5],[2,9]]]]\n[[[7,5],[[0,7],[3,3]]],[[8,[1,5]],9]]\n[[[6,[9,0]],[[0,7],[7,5]]],[[[4,9],0],[[2,3],7]]]\n[[8,[8,[0,1]]],[[2,6],7]]\n[1,[[9,3],1]]\n[[[[6,2],[0,8]],5],[[[9,4],7],[[6,3],6]]]\n[[[8,[4,2]],[4,9]],[7,[[9,0],8]]]\n[1,[[7,3],2]]\n[[[3,[5,9]],[7,[0,4]]],[[[3,0],7],4]]\n[[[1,[8,3]],[4,[2,3]]],[[3,[1,6]],[[1,6],5]]]\n[[[[1,3],2],9],[5,[4,9]]]\n[[[7,[0,6]],2],[[[1,5],[0,7]],[4,9]]]\n[[[5,0],[0,[1,1]]],5]\n[[[[9,3],[0,0]],[[1,3],[7,3]]],[[5,7],[[6,6],[6,5]]]]\n[[[8,0],[9,0]],[[[4,7],4],[5,[2,6]]]]\n"} -->
<!-- livebook:{"reevaluate_automatically":true} -->
```elixir
data =
"input"
|> IO.getn(1_000_000)
|> String.trim()
|> String.split(["\n", "\r\n"], trim: true)
|> Enum.map(&(&1 |> Code.eval_string() |> elem(0)))
```
<!-- livebook:{"reevaluate_automatically":true} -->
```elixir
defmodule D18 do
def add(a, b) do
reduce([a, b])
end
def reduce(l) do
cond do
l = explode(l, _level = 1) ->
{_, l, _} = l
# IO.inspect(l, charlists: false, label: "after explode")
reduce(l)
l = split(l) ->
# IO.inspect(l, charlists: false, label: "after split")
reduce(l)
true ->
l
end
end
def merge([a, b], n) do
[a, merge(b, n)]
end
def merge(n, [a, b]) do
[merge(n, a), b]
end
def merge(a, b) do
a + b
end
def explode([a, b], 5) do
# IO.inspect([a,b], label: "explode")
{a, 0, b}
end
def explode([a, b], level) do
with {aa, n, ab} <- explode(a, level + 1) do
{aa, [n, merge(ab, b)], 0}
end ||
with {ba, n, bb} <- explode(b, level + 1) do
{0, [merge(a, ba), n], bb}
end
end
def explode(_n, _level) do
false
end
def split([a, b]) do
if aa = split(a) do
[aa, b]
else
if bb = split(b) do
[a, bb]
else
false
end
end
end
def split(n) when n >= 10 do
# IO.inspect(n, label: "split")
half = div(n, 2)
[half, n - half]
end
def split(n) do
false
end
def magnitude([a, b]) when is_integer(a) and is_integer(b) do
3 * a + 2 * b
end
def magnitude([a, b]) when is_integer(a) do
magnitude([a, magnitude(b)])
end
def magnitude([a, b]) when is_integer(b) do
magnitude([magnitude(a), b])
end
def magnitude([a, b]) do
magnitude([magnitude(a), magnitude(b)])
end
end
```
## P1
<!-- livebook:{"reevaluate_automatically":true} -->
```elixir
data
|> Enum.reduce(&IO.inspect(D18.add(&2, &1), charlists: false))
|> D18.magnitude()
```
## P2
<!-- livebook:{"reevaluate_automatically":true} -->
```elixir
for a <- data, b <- data, a != b do
[
D18.magnitude(D18.add(a, b)),
D18.magnitude(D18.add(b, a))
]
end
|> List.flatten()
|> Enum.max()
```