Day 13
Mix.install([
{:kino, "~> 0.7.0"}
])
example_input =
Kino.Input.textarea("example input:")
|> Kino.render()
real_input = Kino.Input.textarea("real input:")
Common
parse = fn input ->
input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(&Code.eval_string/1)
|> Enum.map(&elem(&1, 0))
end
defmodule Pair do
def compare(same, same), do: :eq
def compare(left, right) when is_integer(left) and is_integer(right) do
if left < right, do: :lt, else: :gt
end
def compare([], right) when is_list(right), do: :lt
def compare(left, []) when is_list(left), do: :gt
def compare(left, right) when is_integer(left) and is_list(right) do
compare([left], right)
end
def compare(left, right) when is_list(left) and is_integer(right) do
compare(left, [right])
end
def compare([l | left], [r | right]) do
case compare(l, r) do
:eq -> compare(left, right)
val -> val
end
end
end
ExUnit.start(autorun: false)
defmodule PairTest do
use ExUnit.Case, async: true
test "first example" do
assert :lt = Pair.compare([1, 1, 3, 1, 1], [1, 1, 5, 1, 1])
end
test "second example" do
assert :lt = Pair.compare([[1], [2, 3, 4]], [[1], 4])
end
test "third example" do
assert :gt = Pair.compare([9], [[8, 7, 6]])
end
test "fourth example" do
assert :lt = Pair.compare([[4, 4], 4, 4], [[4, 4], 4, 4, 4])
end
test "fifth example" do
assert :gt = Pair.compare([7, 7, 7, 7], [7, 7, 7])
end
test "sixth example" do
assert :lt = Pair.compare([], [3])
end
test "seventh example" do
assert :gt = Pair.compare([[[]]], [[]])
end
test "eighth example" do
assert :gt =
Pair.compare(
[1, [2, [3, [4, [5, 6, 7]]]], 8, 9],
[1, [2, [3, [4, [5, 6, 0]]]], 8, 9]
)
end
end
ExUnit.run()
Part 1
real_input
|> then(parse)
|> Enum.chunk_every(2)
|> Enum.with_index(1)
|> Enum.flat_map(fn {pair, index} -> if Enum.sort(pair, Pair) == pair, do: [index], else: [] end)
|> Enum.sum()
Part 2
divider_packets = [[[2]], [[6]]]
real_input
|> then(parse)
|> Enum.concat(divider_packets)
|> Enum.sort(Pair)
|> Enum.with_index(1)
|> Enum.flat_map(fn {packet, index} -> if packet in divider_packets, do: [index], else: [] end)
|> Enum.product()