Day 13: Distress Signal
Mix.install([:kino, :jason])
Section
input = Kino.Input.textarea("input")
pairs =
input
|> Kino.Input.read()
|> String.split("\n\n")
|> Enum.map(fn line ->
[left, right] = String.split(line, "\n")
{Jason.decode!(left), Jason.decode!(right)}
end)
defmodule Packet do
def compare([], []), do: :eq
def compare([], [_ | _]), do: :lt
def compare([_ | _], []), do: :gt
def compare([x | left], [y | right]) do
case compare(x, y) do
:eq -> compare(left, right)
neq -> neq
end
end
def compare(left, right) when is_list(left), do: compare(left, [right])
def compare(left, right) when is_list(right), do: compare([left], right)
def compare(left, right) when left == right, do: :eq
def compare(left, right) when left < right, do: :lt
def compare(left, right) when left > right, do: :gt
end
pairs
|> Enum.with_index(1)
|> Enum.reduce(0, fn {{left, right}, i}, sum ->
if Packet.compare(left, right) == :lt, do: sum + i, else: sum
end)
divider_packets = [
[[2]],
[[6]]
]
pairs
|> Enum.flat_map(fn {left, right} -> [left, right] end)
|> Enum.concat(divider_packets)
|> Enum.sort(Packet)
|> then(fn ordered ->
divider_packets
|> Enum.map(fn p -> Enum.find_index(ordered, &(&1 == p)) + 1 end)
|> Enum.product()
end)