Advent 2021 - Day 10
Setup
Mix.install([
{:kino, github: "livebook-dev/kino"}
])
input = Kino.Input.textarea("Please paste your input file:")
input =
input
|> Kino.Input.read()
|> String.trim()
|> String.split("\n")
|> Enum.map(&String.graphemes(&1))
Utils
defmodule Utils do
def validate(input) do
returned =
Enum.reduce_while(input, [], fn char, stack ->
push = fn -> {:cont, [char | stack]} end
pop = fn expected ->
[head | tail] = stack
case head do
^expected -> {:cont, tail}
_ -> {:halt, char}
end
end
case char do
"(" -> push.()
"[" -> push.()
"{" -> push.()
"<" -> push.()
")" -> pop.("(")
"]" -> pop.("[")
"}" -> pop.("{")
">" -> pop.("<")
end
end)
if is_list(returned), do: {:ok, returned}, else: {:error, returned}
end
end
Part 1
point_lookup = %{
")" => 3,
"]" => 57,
"}" => 1197,
">" => 25137
}
input
|> Enum.map(&Utils.validate(&1))
|> Enum.filter(fn {status, _} -> status == :error end)
|> Enum.map(fn {_, char} -> point_lookup[char] end)
|> Enum.sum()
Part 2
point_lookup = %{
"(" => 1,
"[" => 2,
"{" => 3,
"<" => 4
}
scores =
input
|> Enum.map(&Utils.validate(&1))
|> Enum.filter(fn {status, _} -> status == :ok end)
|> Enum.map(fn {_, remaining_stack} ->
Enum.reduce(remaining_stack, 0, fn char, acc ->
acc * 5 + point_lookup[char]
end)
end)
|> Enum.sort()
scores
|> Enum.at(length(scores) |> div(2))