Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

--- Day 10: Syntax Scoring ---

2021/day10.livemd

— 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(&amp;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(&amp;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(&amp;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)