Advent of Code 2022 - Day 13
Mix.install([
:kino,
{:kino_aoc, git: "https://github.com/ljgago/kino_aoc"},
:kino_vega_lite
])
Input
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]
"""
{:ok, puzzle_input} = KinoAOC.download_puzzle("2022", "13", System.fetch_env!("LB_AOC_SESSION"))
input_field =
Kino.Input.select("input", [
{test_input, "test_input"},
{puzzle_input, "puzzle_input"}
])
Parse & Prep
parsed =
input_field
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(&Jason.decode!/1)
defmodule Decoder do
def compare([], []), do: :eq
def compare([_ | _], []), do: :gt
def compare([], [_ | _]), do: :lt
def compare([a | resta], [b | restb]) do
case compare(a, b) do
:eq -> compare(resta, restb)
other -> other
end
end
def compare(a, b) when is_integer(a) and is_integer(b) do
cond do
a < b -> :lt
a > b -> :gt
true -> :eq
end
end
def compare(a, b), do: compare(List.wrap(a), List.wrap(b))
end
Part 1
parsed
|> Enum.chunk_every(2)
|> Enum.map(fn [a, b] -> Decoder.compare(a, b) end)
|> Enum.with_index(1)
|> Enum.filter(&(elem(&1, 0) == :lt))
|> Enum.map(&elem(&1, 1))
|> Enum.sum()
Part 2
sorted =
[[[2]], [[6]] | parsed]
|> Enum.sort(Decoder)
divider_packet_1 = Enum.find_index(sorted, &(&1 == [[2]])) + 1
divider_packet_2 = Enum.find_index(sorted, &(&1 == [[6]])) + 1
divider_packet_1 * divider_packet_2