Day 13
Section
defmodule Day13 do
def parse(input) do
input
|> String.split("\n\n", trim: true)
|> Enum.map(fn packets ->
[p1, p2] = String.split(packets, "\n", trim: true)
{p1, _} = Code.eval_string(p1)
{p2, _} = Code.eval_string(p2)
{p1, p2}
end)
end
def cmp(l, r)
def cmp(l, r) when is_integer(l) and is_integer(r) do
cond do
l < r -> :lt
l == r -> :eq
l > r -> :gt
end
end
def cmp(x, x), do: :eq
def cmp([_ | _], []), do: :gt
def cmp([], [_ | _]), do: :lt
def cmp(l, r) when is_list(l) and is_integer(r),
do: cmp(l, [r])
def cmp(l, r) when is_list(r) and is_integer(l),
do: cmp([l], r)
def cmp([hl | tl], [hr | tr]) do
case cmp(hl, hr) do
:lt -> :lt
:gt -> :gt
:eq -> cmp(tl, tr)
end
end
def part_1(input) do
input
|> parse()
|> Enum.with_index(fn {p1, p2}, idx ->
{cmp(p1, p2), idx + 1}
end)
|> Enum.reduce(0, fn {order, idx}, acc ->
if order == :lt, do: acc + idx, else: acc
end)
end
def part_2(input) do
input
|> parse()
|> Enum.flat_map(&Tuple.to_list/1)
|> then(&[[[2]], [[6]] | &1])
|> Enum.sort(&(cmp(&1, &2) == :lt))
|> Enum.with_index(1)
|> Enum.filter(&(elem(&1, 0) in [[[2]], [[6]]]))
|> Enum.map(&elem(&1, 1))
|> Enum.product()
end
end
test_input = """
[1,1,3,1,1]
[1,1,5,1,1]
[[1],[2,3,4]]
[[1],4]
[9]
[[8,7,6]]
[[4,4],4,4]
[[4,4],4,4,4]
[7,7,7,7]
[7,7,7]
[]
[3]
[[[]]]
[[]]
[1,[2,[3,[4,[5,6,7]]]],8,9]
[1,[2,[3,[4,[5,6,0]]]],8,9]
"""
Day13.part_1(test_input)
input = File.read!("day13_input.txt")
Day13.part_1(input)
Day13.part_2(test_input)
Day13.part_2(input)