110 lines
2.5 KiB
Elixir
110 lines
2.5 KiB
Elixir
import AOC
|
|
|
|
|
|
aoc 2021, 18 do
|
|
def p1 do
|
|
input()
|
|
|> Enum.reduce(fn x, acc -> concat(acc, x) |> reduce() end)
|
|
|> to_lists()
|
|
|> magnitude()
|
|
end
|
|
|
|
def p2 do
|
|
numbers = input() |> Enum.to_list()
|
|
|
|
for a <- numbers, b <- numbers, a != b do
|
|
concat(a, b)
|
|
|> reduce()
|
|
|> to_lists()
|
|
|> magnitude()
|
|
end
|
|
|> Enum.max()
|
|
end
|
|
|
|
def magnitude([a, b]) do
|
|
3 * magnitude(a) + 2 * magnitude(b)
|
|
end
|
|
def magnitude(n), do: n
|
|
|
|
def reduce(encoded_snailfish_number) do
|
|
case step(encoded_snailfish_number) do
|
|
{:nop, result} -> result
|
|
{_, result} -> reduce(result)
|
|
end
|
|
end
|
|
|
|
def step([{dl, _} = left, {d, a}, {d, b}, right | rest]) when d > 4 and dl != d do
|
|
{:exploded, [add(left, a), {d - 1, 0}, add(right, b) | rest]}
|
|
end
|
|
def step([{dl, _} = left, {d, a}, {d, _}]) when d > 4 and dl != d do
|
|
{:exploded, [add(left, a), {d - 1, 0}]}
|
|
end
|
|
def step([{d, _}, {d, b}, right | rest]) when d > 4 do
|
|
{:exploded, [{d - 1, 0}, add(right, b) | rest]}
|
|
end
|
|
|
|
def step([{d, n} | rest]) when n >= 10 do
|
|
l = {d + 1, div(n, 2)}
|
|
r = {d + 1, div(n, 2) + rem(n, 2)}
|
|
{:split, [l, r | rest]}
|
|
end
|
|
|
|
def step([]) do
|
|
{:nop, []}
|
|
end
|
|
def step([h | rest]) do
|
|
{op, rest} = step(rest)
|
|
{op, [h | rest]}
|
|
end
|
|
|
|
def add({d, n}, x), do: {d, n + x}
|
|
|
|
def concat(xs, ys), do: deepen(xs ++ ys)
|
|
|
|
def deepen(xs) do
|
|
for {d, x} <- xs, do: {d + 1, x}
|
|
end
|
|
|
|
def to_lists(flat) do
|
|
case to_lists_(flat) do
|
|
{true, unflatter} -> to_lists(unflatter)
|
|
{false, [{0, unflattest}]} -> unflattest
|
|
end
|
|
end
|
|
|
|
def to_lists_([]), do: {false, []}
|
|
def to_lists_([{d, a}, {d, b} | rest]) do
|
|
{true, [{d - 1, [a, b]} | rest]}
|
|
end
|
|
def to_lists_([x | rest]) do
|
|
{recurse, rest} = to_lists_(rest)
|
|
{recurse, [x | rest]}
|
|
end
|
|
|
|
def encoded_to_string(encoded) do
|
|
encoded
|
|
|> to_lists()
|
|
|> inspect(charlists: :as_lists)
|
|
|> String.replace(" ", "")
|
|
end
|
|
|
|
def fst([a, _]), do: a
|
|
def snd([_, b]), do: b
|
|
|
|
|
|
def read_input_line(line, depth \\ 0)
|
|
def read_input_line("[" <> rest, depth), do: read_input_line(rest, depth + 1)
|
|
def read_input_line("]" <> rest, depth), do: read_input_line(rest, depth - 1)
|
|
def read_input_line("," <> rest, depth), do: read_input_line(rest, depth)
|
|
def read_input_line("", _), do: []
|
|
def read_input_line(line, depth) do
|
|
{n, rest} = Integer.parse(line)
|
|
[{depth, n} | read_input_line(rest, depth)]
|
|
end
|
|
|
|
def input() do
|
|
input_stream()
|
|
|> Enum.map(&read_input_line/1)
|
|
end
|
|
|
|
end
|