— Day 10: Syntax Scoring —
Setup
defmodule Setup do
def get_input(prompt) do
case IO.gets(prompt) do
:eof -> ""
line -> line <> get_input(prompt)
end
end
end
input =
Setup.get_input("input")
|> String.split("\n", trim: true)
|> Enum.map(&String.to_charlist/1)
defmodule NavigationSystem do
@openers '[{(<'
@pairs [
'()',
'<>',
'[]',
'{}'
]
def parse(line, stack \\ [])
def parse([], stack) do
{:ok, stack}
end
def parse([c | cs], stack) when c in @openers do
parse(cs, [c | stack])
end
def parse([c | cs], [o | stack]) when [o, c] in @pairs do
parse(cs, stack)
end
def parse([c | _cs], _stack) do
{:error, c}
end
end
part1
input
|> Enum.map(&NavigationSystem.parse/1)
|> Enum.reduce(0, fn
{:ok, _}, acc ->
acc
{:error, c}, acc ->
case c do
?) -> 3 + acc
?] -> 57 + acc
?} -> 1197 + acc
?> -> 25137 + acc
end
end)
part2
input
|> Enum.map(&NavigationSystem.parse/1)
|> Enum.reduce([], fn
{:error, _}, acc ->
acc
{:ok, stack}, acc ->
[
Enum.reduce(stack, 0, fn
?(, acc -> acc * 5 + 1
?[, acc -> acc * 5 + 2
?{, acc -> acc * 5 + 3
?<, acc -> acc * 5 + 4
end)
| acc
]
end)
|> Enum.sort()
|> then(fn scores ->
Enum.at(scores, div(length(scores), 2))
end)