Day13
Mix.install([
{:kino, "~> 0.8.0"},
:poison
])
:ok
Section
input = Kino.Input.textarea("Puzzle input")
List Parser
defmodule ListParser do
def parse(line) do
line
|> do_parse()
end
defp do_parse(str, acc \\ [])
defp do_parse("", acc), do: acc
defp do_parse("]" <> rest, acc) do
{rest, acc}
end
defp do_parse("[" <> rest, acc) do
{rest, value} = do_parse(rest)
do_parse(rest, acc ++ [value])
end
defp do_parse("," <> rest, acc) do
do_parse(rest, acc)
end
defp do_parse(rest, acc) do
{v, rest} = Integer.parse(rest)
# {rest, v} = take_number(rest, "")
do_parse(rest, acc ++ [v])
end
end
{:module, ListParser, <<70, 79, 82, 49, 0, 0, 9, ...>>, {:do_parse, 2}}
Pair Comparer
defmodule PairComparer do
def compare([], []), do: :eq
def compare([], _), do: :lt
def compare(_, []), do: :gt
def compare(left, right) when is_integer(left) and is_integer(right) do
cond do
left < right -> :lt
left > right -> :gt
true -> :eq
end
end
def compare([left | left_rest], [right | right_rest]) do
case compare(left, right) do
:eq -> compare(left_rest, right_rest)
res -> res
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)
end
{:module, PairComparer, <<70, 79, 82, 49, 0, 0, 8, ...>>, {:compare, 2}}
Read input and parse lists
input =
input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(&ListParser.parse/1)
[
[[[8, 6, [], 2], '\a', [8, 0, [7, 0], [[5, 6], 10, '\n']], [3, 8, [], ['\b\t', 4]], []]],
[[[3, [2, [9, 4, 4], 1], [[3], [], [7, 10, 6, 6], [8, 6]]], [[8, 5], [2, [], '\a']]]],
[[[[2, [5], '\n\n']], [2]]],
[
[
'\a\n',
[6, [[2, 10, 7, 9, 5], 7, 7, 0], 2, [[5, 10]], [[9, 1], [], [5, 7, 6], [2], [3]]],
[[[5, 0, 10], 2, 8, [5, 6, 2, 2, 10], '\t'], 5, 8, 6, []],
[
[[0], [2, 1, 2, 1, 0], [9, 0], [0], [1, 3, 10, 1]],
[5, '\b', [], 8, [3, 8, 7, 3]],
[6, [3], 7, [8, 2], []]
]
]
],
[[[[[9, 6, 10, 5, 2], [0, 10, 6, 8]], 2, [[4, 9, 3], 4], [9, [], 0, [7, 6, 2], 7]], []]],
[
[
[6, [5], [], '\t', [7, 4, [6], 10]],
[[[6, 3, 6, 4]], 2, 6],
[3, [[9, 0, 6], [8, 4, 6], 10], [3, 0, 5], []],
[[2, [2, 5, 3, 7, 1], 5], ['\b', []]]
]
],
[
[
[],
[4, [], 0, [], 6],
[[[5], [4, 3, 6]], [[7, 6], 5], [[3, 9], 2], 7],
[4, [], 2, [3, [], 10]]
]
],
[
[
[[0, 2], [6, [5, 9, 8], [1, 8, 1]]],
[[[1, 3, 0], [], 0, 10], [6], 3],
[[[1, 1, 6, 2, 1]], 9],
[[[5, 0, 4], 5, [1, 2, 5, 10, 2]], [[7, 8, 4], 1]]
]
],
[[[1], [10, [10, 4, [0]]], [[[7, 6], [2, 2, 0, 7], '\n']]]],
[[[[10, [5, 8], [2, 10, 2], [], 7], [2], 1]]],
[[[[4, 4, [7, 4, 5]], 1, [[3], 6, [6, 7]], 6]]],
[[[4], [[], [0]], [[[10, 7, 2, 8], 4], 9, [], [[3, 5, 1], []]], [[5, []], [], [4, 2], 9, 1]]],
[[[[], 8, 4], [[7, [5, 4, 8, 8], 4], 7], [6], [2, 0]]],
[[[[1, 0, 7, [5, 3, 5], []], 8, ['\t\a', [], [], 9, 10], 0], [[], 1, 0, []]]],
[[[6, [], [5, 3, 7]], '\a', [['\n', [5], 9], 7]]],
[
[
[[[4, 3, 10, 8], 4, [3, 1, 7], [0, 8, 0, 5, 6]], [[]]],
[],
[[3, '\t'], [[7, 0, 6, 9, 7], 8, [1, 10, 3], 1], 0]
]
],
[
[
[[9, [5, 1, 8], 8, [4, 2, 0, 4], 4], [4, 0], 2],
[1, [2], 9],
[[], 9, 5, [1], 9],
[[3, 5], [[2, 9, 7, 9], [4, 9, 7, 9, 6], 0, [0, 4, 7]], 5, [4, 5, 5]],
[]
]
],
[[[[[], []], 3, 0, 6]]],
[
[
[10, 5, 4, 2],
[6, [[9, 9, 3, 8, 0]], 5],
[2, [0, 9, []]],
[[], [1, 10, 4, [9, 4], []]],
[[[5, 7, 9], [], [5, 10]], [5, 7]]
]
],
[[[], [10, 6, 9, 9, 0]]],
[[[], [7, [[6, 0, 6, 7]], 8, [4, [3], [5, 8], 5], 10]]],
[
[
[[8, [4], [9, 0, 1, 0, 3], 9, [5, 1, 10]], 3],
[[1, 5, 4, 4], [[0, 6, 2, 2], 2, 3, [0, 3, 6]], 0, [[0, 6], 3, 10]],
[10, 10, 0, 8, [[0], [5, 9, 5, 1], [10, 0, 10, 9]]],
[5, 2]
]
],
[
[
[[[7, 0], [6, 0, 2, 8, 7], 0], 5, ['\a', [6, 0, 5]]],
[2, [[6, 5, 1, 10], [2, 0]], 0],
[['\b', 9, '\t\n\a', [0]]]
]
],
[
[
[[[7, 10, 2], 10, 10, [1, 2], [5, 7, 2]], [7, 3, [9, 4, 5, 10, 5], 7], 5, 9],
[1, 1, [[4, 0, 10, 6], [3, 0], [2, 7, 2]]],
[],
[[4, 8, 0, 5, [5, 3, 5, 7, 0]], 6]
]
],
[[[], []]],
[
[
[[[1], 5, [1, 10, 1, 4, 1], '\t\b']],
[4, [[0, 3, 0], [], [3, 5], [9, 1, 0], 2]],
[[5, 1, 8, 9, [5, 6]], [6, 2, 5, 8, [1]]],
[]
]
],
[[[10, 9, 0, [9, 5, 1, [5, 8, 9, 7]]], [4, [[], 7, 4]]]],
[
[
[[1], 4, 4, [[], [2], 8, [6, 2, 6], []], 8],
[[3, [], [1, 6, 6, 4, 9], [1, 2, 8, 4, 3]], [[], [0, 9, 9], [6, 5], [0, 6, 3, 3, 2], 3]],
[[3], [5], 2],
[[], 2, [[2, 3, 4, 6], [1, 7, 8, 10]]],
[9, 3]
]
],
[[[], [2, [5, 8, [2, 3, 5, 6, 0], [8, 4, 9, 7, 1]], [[8, 0], 9, 1, 2, [2, 5, 0]], 10]]],
[[[8, [], 9, 6], [4, 2, 10, [], 9]]],
[[[10, 8, '\t', 9, 8], [[], 0]]],
[
[
[1, [9, 1, [6, 8]], 9, [[0], '\a', [0, 5, 5], [3, 5, 10, 7, 3], [1, 2, 9]], 8],
[9, 4, 9, 9],
[4, 3, [[2, 6, 7, 4, 7], [0, 5, 2], [2, 0, 2, 7, 6]], 4],
[[[9, 2, 9, 4]], [5], [0, '\a']],
[9, [[6], [3], [10, 0], 8, []], [], 1, 8]
]
],
[
[
[[8, 4], 2, [[2], '\t', [5, 9, 3, 9], [5], [5, 5]], 2, 4],
[8, 6, 3, 8],
[1, ['\a', [2, 5, 9, 1], [2, 0], [8, 2, 4, 8]]],
[1, 4],
[8, 9, [7, 5, 4, [4, 10, 0, 8]], [1, '\n', 8], 8]
]
],
[
[
[[[2, 2, 8, 10], 7, 0, 10], 7, 2],
[5, 1, [4, 5], [3, 0, 5, [0], 1], [[2], [2, 7, 4, 7], 8, 9]],
'\a\b\b\t',
[[1, 0, 6, 4], [[1, 3, 0], 10, 1, 10, 0], 7, 9, 0],
[]
]
],
[[[], [4, 6, [[1, 5, 8, 10], [], [7, 0, 3, 10]]], []]],
[[[[], 4, 4], [7, [], 10, ['\b', 3, [8, 1, 5], [5, 4]]], [[], [[1, 4]], 2, [[], 7, 5], 3]]],
[
[
[[[5, 7], 10, 9, [6, 0], [4, 9, 6, 7, 1]], []],
[5, [[5]]],
[[10, []]],
[4, [[0], 3, [7, 0, 3], 9, 9]]
]
],
[
[
[[], '\t', 9, 6],
[],
[2, 6, 5],
[8, [8, [], [10, 3, ...], [9, ...]], 10],
[[[1], [7, 5, 6, ...]], 7, [6, [], []]]
]
],
[[[[[4, 3, 3], [], 1], [[], 5, 9, 0, 2], [[6], [5]], [0, 4, 0, 6], 10]]],
[[[], [3, [[7, 1], '\b', '\n', [7, ...], '\a']]]],
[
[
[[], [5], [1, 6, 1, 4, ...], 0],
[5, [[6]], [[0, 3, ...], [3, ...]]],
[[3], [[4, 2, ...], [5]], [], 2, 9],
[6, 0]
]
],
[[[], '\n']],
[[[8, [], [[7, ...], [...]], 0], [['\n', [6, ...], 6], 5, 4, []]]],
[[[3, 3, 1, '\b\n', ...], [10, 7, [...]], [0], [], []]],
[['\b\n', [[[...], ...], [...], ...], [[...]]]],
[[[3, [...], ...], [0, ...]]],
[[[0], [...], ...]],
[[[...]]],
[[...]],
[...],
...
]
Part 1
input
|> Enum.chunk_every(2)
|> Enum.with_index()
|> Enum.filter(fn {[a, b], _index} ->
PairComparer.compare(a, b) == :lt
end)
|> Enum.map(fn {_, index} -> index + 1 end)
|> Enum.sum()
5625
Part 2
sorted =
input
|> Kernel.++([[[2]], [[6]]])
|> Enum.sort(&(PairComparer.compare(&1, &2) == :lt))
|> Enum.with_index()
{_, packet1_index} = Enum.find(sorted, fn {e, _index} -> e == [[2]] end)
{_, packet2_index} = Enum.find(sorted, fn {e, _index} -> e == [[6]] end)
(packet1_index + 1) * (packet2_index + 1)
23111