Day 13
Section
defmodule Day13 do
def parse_input(path) do
path
|> File.stream!()
|> Stream.map(&String.trim/1)
|> Stream.reject(&(&1 == ""))
|> Stream.map(&Code.eval_string/1)
|> Enum.map(&elem(&1, 0))
end
def part1(input) do
input
|> Enum.chunk_every(2)
|> Enum.with_index(1)
|> Enum.filter(fn {[a, b], _} -> compare(a, b) in [:lt, :eq] end)
|> Enum.map(&elem(&1, 1))
|> Enum.sum()
end
@driver [
[[2]],
[[6]]
]
def part2(input) do
@driver
|> Kernel.++(input)
|> Enum.sort(fn a, b -> compare(a, b) in [:lt, :eq] end)
|> Enum.with_index(1)
|> Enum.filter(fn {packet, _} -> packet in @driver end)
|> Enum.map(&elem(&1, 1))
|> Enum.product()
end
defp compare([], []), do: :eq
defp compare([], [_ | _]), do: :lt
defp compare([_ | _], []), do: :gt
defp compare([h1], [h2]) when is_integer(h1) and is_integer(h2) do
cond do
h1 > h2 -> :gt
h1 < h2 -> :lt
true -> :eq
end
end
defp compare([h1 | t1], [h2 | t2]) do
case compare(List.wrap(h1), List.wrap(h2)) do
:eq -> compare(t1, t2)
x -> x
end
end
end
input = Day13.parse_input("#{__DIR__}/day13.txt")
Day13.part1(input)
Day13.part2(input)