Advent 2022 - Day 13
Mix.install([
{:kino, github: "livebook-dev/kino"}
])
:ok
Setup
input = Kino.Input.textarea("Please paste your input file:")
pairs =
input
|> Kino.Input.read()
|> String.split("\n\n")
|> Enum.map(&String.split(&1, "\n"))
[
["[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]"]
]
pairs =
pairs
|> Enum.map(fn pair ->
pair
|> Enum.map(&Code.eval_string/1)
|> Enum.map(&elem(&1, 0))
end)
[
[[1, 1, 3, 1, 1], [1, 1, 5, 1, 1]],
[[[1], [2, 3, 4]], [[1], 4]],
['\t', [[8, 7, 6]]],
[[[4, 4], 4, 4], [[4, 4], 4, 4, 4]],
['\a\a\a\a', '\a\a\a'],
[[], [3]],
[[[[]]], [[]]],
[[1, [2, [3, [4, [5, 6, 7]]]], 8, 9], [1, [2, [3, [4, [5, 6, 0]]]], 8, 9]]
]
Utils
defmodule PacketValidator do
def validate(a, b) when is_integer(a) and is_list(b), do: validate([a], b)
def validate(a, b) when is_list(a) and is_integer(b), do: validate(a, [b])
def validate([], []), do: nil
def validate(_a, []), do: false
def validate([], _b), do: true
def validate(a, b) when is_list(a) and is_list(b) do
resp = validate(hd(a), hd(b))
if resp == nil, do: validate(tl(a), tl(b)), else: resp
end
def validate(a, b) when is_integer(a) and is_integer(b) do
cond do
a == b -> nil
a > b -> false
a < b -> true
end
end
end
{:module, PacketValidator, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:validate, 2}}
Part 1
pairs
|> Enum.map(fn [l, r] ->
PacketValidator.validate(l, r)
end)
|> Enum.with_index()
|> Enum.filter(fn {valid, _index} -> valid end)
|> Enum.map(&(elem(&1, 1) + 1))
|> Enum.sum()
13
Part 2
all_packets = pairs |> Enum.reduce(&(&1 ++ &2))
additional_packet_1 = [[2]]
additional_packet_2 = [[6]]
all_packets_plus_extra = all_packets ++ [additional_packet_1, additional_packet_2]
sorted = all_packets_plus_extra |> Enum.sort(&PacketValidator.validate/2)
[
[],
[[]],
[[[]]],
[1, 1, 3, 1, 1],
[1, 1, 5, 1, 1],
[[1], [2, 3, 4]],
[1, [2, [3, [4, [5, 6, 0]]]], 8, 9],
[1, [2, [3, [4, [5, 6, 7]]]], 8, 9],
[[1], 4],
[[2]],
[3],
[[4, 4], 4, 4],
[[4, 4], 4, 4, 4],
[[6]],
'\a\a\a',
'\a\a\a\a',
[[8, 7, 6]],
'\t'
]
first = Enum.find_index(sorted, &(&1 == additional_packet_1)) + 1
second = Enum.find_index(sorted, &(&1 == additional_packet_2)) + 1
first * second
140