Day 18
Input
input =
File.stream!("day18.txt")
|> Enum.map(&elem(Code.eval_string(&1), 0))
[
[[[6, [8, 3]], [2, 0]], [[[9, 5], [9, 1]], 3]],
[[[9, [2, 2]], [5, 4]], [[[2, 2], [9, 6]], '\a\a']],
[[[0, [3, 2]], 1], [[0, [2, 8]], [2, [0, 4]]]],
[[4, 4], [[[7, 0], 5], [3, 1]]],
[[5, 4], 1],
[[[[7, 6], 4], 9], [[9, 1], 9]],
[[[1, '\a\b'], ['\a\a', [1, 6]]], [1, [6, [7, 1]]]],
[[[[6, 8], [5, 6]], [[1, 1], 8]], [[[2, 0], [3, 1]], [2, [2, 6]]]],
[[[6, 3], [3, [7, 1]]], 8],
[[[9, 4], [3, [0, 6]]], [[2, [3, 6]], ['\t\b', [1, 6]]]],
[9, [0, [[0, 7], 2]]],
[[[[8, 4], 7], [[9, 2], [0, 9]]], ['\a\t', [8, [0, 9]]]],
[[1, 1], [[5, [3, 8]], [3, [4, 7]]]],
[[[9, [2, 9]], [2, [2, 9]]], [[[3, 5], 5], [[3, 3], 2]]],
[[[[5, 4], 9], 0], [[[5, 7], 2], [[5, 2], 9]]],
[[2, [[1, 0], [6, 2]]], 0],
[[[3, 7], [7, 6]], [[[2, 8], 5], [3, '\t\a']]],
[[2, [2, '\b\b']], [['\t\t', [1, 1]], [[8, 6], [0, 3]]]],
[[8, 1], [3, 5]],
[[7, [[7, 6], [2, 0]]], 4],
[[5, 4], [[1, 3], [5, [2, 8]]]],
'\a\t',
[[[[6, 9], 0], [1, [5, 0]]], [[[6, 4], 3], 7]],
[[[[3, 7], 3], [2, 6]], [[0, 4], '\t\t']],
[[[[1, 5], [5, 0]], [9, 4]], [[[8, 3], 3], [8, [3, 6]]]],
[[[[3, 7], 5], [[8, 5], [1, 5]]], [[0, 6], [3, 4]]],
[[[[4, 0], 2], [7, [8, 4]]], [0, [5, '\a\b']]],
[[[[0, 8], [0, 4]], [9, 3]], [[[5, 4], [4, 8]], [[1, 6], [5, 4]]]],
[[0, [0, 3]], [[3, [1, 5]], [[9, 6], [0, 6]]]],
[[9, [8, 4]], [7, 1]],
[[[[1, 9], '\a\a'], 9], [[6, [4, 5]], [8, [3, 2]]]],
[5, [[2, [9, 5]], [3, [4, 0]]]],
[[[6, 2], [[1, 8], 5]], 6],
[[8, [6, [6, 4]]], [0, ['\t\b', 7]]],
[[[[6, 3], [8, 0]], [8, [2, 7]]], 8],
[[[6, [3, 6]], [[4, 0], [4, 7]]], [0, [[4, 0], [4, 5]]]],
[[[3, [8, 1]], 1], [2, 3]],
[[[6, [7, 0]], [[3, 5], [3, 4]]], 7],
[[[[8, 0], 3], 8], [[[1, 6], 3], [[0, 5], 2]]],
[[[3, 7], ['\t\b', 8]], [[[8, 4], 7], [3, [1, 7]]]],
[[[0, 5], [[5, 5], '\a\b']], [9, [5, [2, 2]]]],
[[2, 9], [[[7, 4], 4], [[8, 0], [6, 9]]]],
[[['\a\b', '\b\b'], 0], 9],
[[[4, [0, 6]], [[5, 9], [0, ...]]], [3, [6, 7]]],
[[[7, [6, ...]], [5, [...]]], [[[3, ...], 6], [[...], ...]]],
[3, [[[...], ...], [...]]],
[[[3, ...], [...]], [[...], ...]],
[['\t\a', ...], [...]],
[[...], ...],
[...],
...
]
defmodule Day18 do
def add(a, b) do
sum = reduce([a, b])
# IO.puts("""
# #{inspect(a, charlists: :as_list)}
# + #{inspect(b, charlists: :as_list)}
# = #{inspect(sum, charlists: :as_list)}
# """)
sum
end
defp reduce(list) do
# First try to explode
# If that returned list in the same form, then try to split it
# If all above returned input list, then we have reached fixed point
with ^list <- explode(list),
^list <- split(list) do
list
else
new_list -> reduce(new_list)
end
end
defp explode(list) do
{_, _, exploded} = explode(list, 0)
exploded
end
defp explode(num, _) when is_number(num), do: {0, 0, num}
defp explode([a, b], 4), do: {a, b, 0}
defp explode([a, b], n) do
{la, ra, na} = explode(a, n + 1)
{lb, rb, nb} = explode(explode_add(ra, b), n + 1)
{la, rb, [explode_add(na, lb), nb]}
end
defp explode_add([a, b], v), do: [a, explode_add(b, v)]
defp explode_add(v, [a, b]), do: [explode_add(v, a), b]
defp explode_add(a, b), do: a + b
defp split(n) when n in 0..9, do: n
defp split(n) when is_integer(n), do: [div(n, 2), div(n + 1, 2)]
defp split([a, b]) do
with {:a, ^a} <- {:a, split(a)},
{:b, ^b} <- {:b, split(b)} do
[a, b]
else
{:a, mod} -> [mod, b]
{:b, mod} -> [a, mod]
end
end
def magnitude(n) when is_number(n), do: n
def magnitude([a, b]), do: 3 * magnitude(a) + 2 * magnitude(b)
end
{:module, Day18, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:magnitude, 1}}
Task 1
flip = fn f -> &f.(&2, &1) end
input
|> Enum.reduce(flip.(&Day18.add/2))
|> IO.inspect(charlists: :as_list)
|> Day18.magnitude()
[[[[7, 7], [7, 8]], [[8, 7], [0, 7]]], [[[6, 6], [6, 7]], 6]]
3411
Task 2
for a <- input,
b <- input,
a != b,
m1 = Day18.magnitude(Day18.add(a, b)),
m2 = Day18.magnitude(Day18.add(b, a)),
reduce: 0 do
acc -> max(acc, max(m1, m2))
end
4680