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

Day 10: Syntax Scoring

2021/10.livemd

Day 10: Syntax Scoring

Intro

https://adventofcode.com/2021/day/10

Input

input_test =
  """
  [({(<(())[]>[[{[]{<()<>>
  [(()[<>])]({[<{<<[]>>(
  {([(<{}[<>[]}>{[]{[(<()>
  (((({<>}<{<{<>}{[]{[]{}
  [[<[([]))<([[{}[[()]]]
  [{[{({}]{}}([{[{{{}}([]
  {<[[]]>}<{[{[{[]{()[[[]
  [<(<(<(<{}))><([]([]()
  <{([([[(<>()){}]>(<<{{
  <{([{{}}[<[[[<>{}]]]>[]]
  """
  |> String.split(["\n"], trim: true)
  |> Enum.map(fn x -> String.graphemes(x) end)
[
  ["[", "(", "{", "(", "<", "(", "(", ")", ")", "[", "]", ">", "[", "[", "{", "[", "]", "{", "<",
   "(", ")", "<", ">", ">"],
  ["[", "(", "(", ")", "[", "<", ">", "]", ")", "]", "(", "{", "[", "<", "{", "<", "<", "[", "]",
   ">", ">", "("],
  ["{", "(", "[", "(", "<", "{", "}", "[", "<", ">", "[", "]", "}", ">", "{", "[", "]", "{", "[",
   "(", "<", "(", ")", ">"],
  ["(", "(", "(", "(", "{", "<", ">", "}", "<", "{", "<", "{", "<", ">", "}", "{", "[", "]", "{",
   "[", "]", "{", "}"],
  ["[", "[", "<", "[", "(", "[", "]", ")", ")", "<", "(", "[", "[", "{", "}", "[", "[", "(", ")",
   "]", "]", "]"],
  ["[", "{", "[", "{", "(", "{", "}", "]", "{", "}", "}", "(", "[", "{", "[", "{", "{", "{", "}",
   "}", "(", "[", "]"],
  ["{", "<", "[", "[", "]", "]", ">", "}", "<", "{", "[", "{", "[", "{", "[", "]", "{", "(", ")",
   "[", "[", "[", "]"],
  ["[", "<", "(", "<", "(", "<", "(", "<", "{", "}", ")", ")", ">", "<", "(", "[", "]", "(", "[",
   "]", "(", ")"],
  ["<", "{", "(", "[", "(", "[", "[", "(", "<", ">", "(", ")", ")", "{", "}", "]", ">", "(", "<",
   "<", "{", "{"],
  ["<", "{", "(", "[", "{", "{", "}", "}", "[", "<", "[", "[", "[", "<", ">", "{", "}", "]", "]",
   "]", ">", "[", "]", "]"]
]
input =
  File.read!("input10.txt")
  |> String.split(["\n"], trim: true)
  |> Enum.map(fn x -> String.graphemes(x) end)
[
  ["{", "[", "<", "(", "{", "(", "<", "(", "<", "{", "(", "(", "<", "(", "(", ")", "(", ")", ")",
   "[", "(", ")", "<", ">", "]", ">", "(", "{", "[", "]", "[", "]", "}", "{", "<", ">", "{", "}",
   "}", ")", ")", "[", "[", "(", "{", "}", "[", "]", ")", ...],
  ["<", "{", "<", "(", "{", "(", "[", "{", "{", "<", "[", "[", "{", "(", "{", "}", ")", "(", "{",
   "}", "<", ">", ")", "}", "{", "<", "<", ">", "<", ">", ">", "<", "<", ">", "(", ")", ")", "}",
   "]", "(", "<", "<", "[", "]", "(", ")", ">", "(", ...],
  ["{", "(", "(", "{", "<", "[", "[", "{", "(", "{", "[", "<", "<", "(", "{", "}", "<", ">", ")",
   "<", "{", "}", "[", "]", ">", ">", ">", "{", "(", "<", "(", ")", "[", "]", ">", "[", "[", "]",
   "[", "]", "]", ")", "<", "<", "{", "}", "(", ...],
  ["[", "(", "(", "(", "[", "{", "(", "{", "[", "{", "[", "<", "<", "(", "(", ")", "{", "}", ")",
   "[", "[", "]", "(", ")", "]", ">", "<", "(", "[", "]", ")", "{", "(", ")", "(", ")", "}", ">",
   ">", "<", "{", "[", "(", ")", "{", "}", ...],
  ["<", "{", "[", "<", "[", "(", "<", "[", "[", "{", "{", "{", "(", "{", "(", ")", "(", ")", "}",
   "[", "<", ">", "[", "]", "]", ")", "<", "[", "<", ">", "{", "}", "]", "[", "[", "]", "(", ")",
   "]", "]", "}", "}", "(", "[", "(", ...],
  ["<", "{", "(", "<", "(", "<", "[", "<", "<", "<", "{", "<", "(", "[", "{", "}", "(", ")", "]",
   "(", "{", "}", "(", ")", ")", ")", "[", "(", "{", "}", "(", ")", ")", "]", ">", "[", "(", "(",
   "(", ")", "(", ")", ")", "(", ...],
  ["{", "{", "[", "(", "(", "(", "<", "{", "[", "{", "(", "(", "{", "{", "{", "}", "}", "[", "[",
   "]", "[", "]", "]", "}", "[", "[", "{", "}", "{", "}", "]", "]", ")", ")", "(", "(", "(", "(",
   "[", "]", "<", ">", ")", ...],
  ["{", "(", "<", "(", "[", "{", "[", "(", "(", "{", "(", "<", "(", "{", "(", ")", "[", "]", "}",
   ")", "[", "{", "{", "}", "(", ")", "}", "[", "(", ")", "[", "]", "]", "]", ">", "[", "<", "{",
   "(", ")", "<", ">", ...],
  ["[", "<", "[", "(", "[", "<", "{", "{", "(", "(", "{", "(", "<", "{", "[", "]", "{", "}", "}",
   "(", "[", "]", "[", "]", ">", ">", "(", "{", "[", "]", "<", ">", "}", "{", "(", ")", "{", "}",
   "}", ")", ")", ...],
  ["[", "[", "<", "(", "[", "{", "{", "<", "[", "[", "<", "<", "<", "<", "[", "]", "<", ">", ">",
   "[", "[", "]", "<", ">", "]", ">", "[", "(", "[", "]", "(", ")", "}", "[", "{", "}", "[", "]",
   "]", "]", ...],
  ["{", "<", "(", "{", "<", "{", "{", "(", "(", "(", "<", "{", "{", "[", "[", "]", "[", "]", "]",
   "<", "<", ">", "[", "]", ">", "}", "}", "(", "[", "{", "<", ">", "(", ")", "}", "[", "[", "]",
   "{", ...],
  ["<", "[", "(", "{", "(", "[", "(", "{", "{", "<", "[", "{", "{", "[", "(", ")", "[", "]", "]",
   "[", "(", ")", "<", ">", "]", "}", "}", "<", "(", "[", "[", "]", "]", "<", "(", ")", ">", ")",
   ...],
  ["(", "[", "<", "{", "[", "<", "{", "[", "<", "{", "{", "<", "{", "[", "(", ")", "{", "}", "]",
   "(", "(", ")", "{", "}", ")", ">", "(", "[", "{", "}", "(", ")", "]", "(", "<", ">", "<", ...],
  ["{", "[", "[", "{", "(", "<", "[", "(", "(", "{", "{", "[", "<", "[", "(", ")", "[", "]", "]",
   "(", "<", ">", "[", "]", ")", ">", "(", "{", "{", "}", "<", ">", "}", "[", "[", "]", ...],
  ["(", "<", "[", "{", "[", "(", "<", "<", "[", "[", "{", "[", "(", "{", "(", ")", "{", "}", "}",
   "[", "[", "]", "<", ">", "]", ")", "(", "[", "<", ">", "(", ")", "]", "(", "{", ...],
  ["{", "{", "{", "[", "[", "[", "<", "{", "<", "[", "<", "[", "<", "{", "(", ")", "<", ">", "}",
   "<", "(", ")", "<", ">", ">", ">", "]", "{", "{", "(", "{", "}", "<", ">", ...],
  ["[", "[", "[", "{", "(", "[", "<", "[", "[", "(", "(", "(", "<", "<", "[", "]", "(", ")", ">",
   "(", "(", ")", "(", ")", ")", ">", "[", "{", "{", "}", "[", "]", "}", ...],
  ["[", "{", "{", "{", "{", "(", "<", "(", "[", "<", "<", "[", "{", "[", "<", ">", "{", "}", "]",
   "}", "{", "<", "{", "}", "<", ">", ">", "<", "<", ">", "(", ")", ...],
  ["<", "[", "[", "{", "[", "[", "{", "[", "(", "<", "<", "{", "{", "{", "{", "}", "}", "}", "(",
   "{", "(", ")", "{", "}", "}", "[", "[", "]", "[", "]", "]", ...],
  ["[", "{", "<", "[", "<", "<", "(", "[", "(", "<", "[", "[", "[", "(", "(", ")", "<", ">", ")",
   "{", "<", ">", "(", ")", "}", "}", "]", "{", "(", "{", ...],
  ["{", "{", "(", "{", "[", "<", "(", "<", "{", "<", "{", "{", "(", "{", "<", ">", "<", ">", "}",
   ")", "<", "{", "{", "}", "[", "]", "}", "{", "[", ...],
  ["(", "[", "<", "[", "[", "(", "{", "(", "<", "<", "(", "{", "{", "<", "{", "}", "[", "]", ">",
   "[", "<", ">", "<", ">", "]", "}", "}", ")", ...],
  ["<", "[", "(", "(", "(", "{", "<", "(", "<", "{", "{", "[", "(", "{", "[", "]", "{", "}", "}",
   "{", "[", "]", "{", "}", "}", ")", "(", ...],
  ["{", "{", "[", "<", "{", "[", "(", "(", "{", "{", "(", "[", "<", "[", "(", ")", "(", ")", "]",
   "{", "<", ">", "(", ")", "}", ">", ...],
  ["(", "{", "[", "[", "[", "<", "(", "[", "(", "<", "{", "(", "[", "[", "<", ">", "[", "]", "]",
   "]", "[", "{", "(", ")", "{", ...],
  ["(", "[", "[", "[", "<", "(", "(", "<", "{", "(", "{", "(", "[", "{", "(", ")", "[", "]", "}",
   "{", "(", ")", "[", "]", ...],
  ["[", "(", "{", "(", "(", "(", "[", "<", "(", "(", "(", "[", "[", "{", "<", ">", "{", "}", "}",
   "<", "[", "]", "<", ...],
  ["{", "<", "(", "[", "(", "{", "<", "[", "(", "(", "{", "<", "(", "(", "[", "]", "(", ")", ")",
   "{", "<", ">", ...],
  ["{", "[", "[", "{", "[", "[", "<", "[", "[", "[", "{", "{", "{", "(", "[", "]", "[", "]", ")",
   "[", "<", ...],
  ["{", "<", "(", "{", "(", "{", "<", "{", "(", "(", "[", "[", "(", "{", "[", "]", "(", ")", "}",
   "(", ...],
  ["{", "(", "[", "[", "(", "(", "<", "<", "[", "[", "(", "<", "[", "(", "(", ")", "{", "}", ")",
   ...],
  ["(", "[", "[", "<", "[", "[", "[", "(", "{", "[", "<", "[", "[", "[", "{", "}", "[", "]", ...],
  ["[", "<", "{", "<", "{", "[", "[", "[", "<", "{", "[", "{", "<", "(", "{", "}", "[", ...],
  ["<", "[", "{", "<", "{", "[", "{", "{", "<", "<", "{", "<", "[", "[", "(", ")", ...],
  ["(", "[", "<", "<", "{", "{", "{", "<", "(", "[", "<", "<", "{", "[", "(", ...],
  ["[", "(", "(", "{", "{", "[", "{", "{", "[", "<", "<", "[", "<", "(", ...],
  ["<", "{", "(", "<", "<", "(", "<", "[", "(", "<", "<", "{", "[", ...],
  ["[", "{", "{", "[", "(", "<", "(", "(", "(", "{", "(", "(", ...],
  ["<", "[", "(", "[", "(", "<", "[", "(", "[", "[", "(", ...],
  ["<", "[", "{", "[", "(", "{", "<", "(", "[", "[", ...],
  ["[", "[", "[", "[", "[", "{", "{", "[", "[", ...],
  ["(", "[", "[", "[", "[", "[", "{", "[", ...],
  ["<", "[", "{", "<", "[", "(", "<", ...],
  ["{", "[", "<", "[", "{", "{", ...],
  ["<", "[", "[", "<", "<", ...],
  ["{", "<", "{", "{", ...],
  ["{", "<", "(", ...],
  ["(", "[", ...],
  ["<", ...],
  [...],
  ...
]

Part 1

i = [
  "{",
  "(",
  "[",
  "(",
  "<",
  "{",
  "}",
  "[",
  "<",
  ">",
  "[",
  "]",
  "}",
  ">",
  "{",
  "[",
  "]",
  "{",
  "[",
  "(",
  "<",
  "(",
  ")",
  ">"
]

# i = [ "{", "(", ")", "}"]
# i = [ "(", ">"]
# PUSH
# []++x

# POP
# List.pop_at(l, -1)

defmodule Stack do
  def push(list, item) do
    list ++ [item]
  end

  def pop(list) do
    List.pop_at(list, -1)
  end

  def valid_pair?("(", ")"), do: true
  def valid_pair?("[", "]"), do: true
  def valid_pair?("{", "}"), do: true
  def valid_pair?("<", ">"), do: true
  def valid_pair?(_, _), do: false

  def is_start?("("), do: true
  def is_start?("["), do: true
  def is_start?("{"), do: true
  def is_start?("<"), do: true
  def is_start?(_), do: false

  def score(")"), do: 3
  def score("]"), do: 57
  def score("}"), do: 1197
  def score(">"), do: 25137

  def score2(")"), do: 1
  def score2("]"), do: 2
  def score2("}"), do: 3
  def score2(">"), do: 4

  def analyze(in_data) do
    analyze(in_data, [])
  end

  def close("("), do: ")"
  def close("["), do: "]"
  def close("{"), do: "}"
  def close("<"), do: ">"

  def analyze([], []) do
    {:valid, 0}
  end

  def analyze([], stack) do
    {:incomplete, stack}
  end

  def analyze(in_data, stack) do
    {element, data} = List.pop_at(in_data, 0)

    case is_start?(element) do
      true ->
        analyze(data, push(stack, element))

      false ->
        {element_from_stack, new_stack} = pop(stack)

        case valid_pair?(element_from_stack, element) do
          true -> analyze(data, new_stack)
          false -> {:corrupted, element}
        end
    end
  end
end

input_test
|> Enum.map(fn i -> Stack.analyze(i) end)
|> Enum.filter(fn {status, _char} -> status == :corrupted end)
|> Enum.map(fn {:corrupted, char} -> Stack.score(char) end)
|> Enum.sum()
26397
input
|> Enum.map(fn i -> Stack.analyze(i) end)
|> Enum.filter(fn {status, _char} -> status == :corrupted end)
|> Enum.map(fn {:corrupted, char} -> Stack.score(char) end)
|> Enum.sum()
299793

Correct: 299793

Part 2

values =
  input_test
  |> Enum.map(fn i -> Stack.analyze(i) end)
  |> Enum.filter(fn {status, _char} -> status == :incomplete end)
  |> Enum.map(fn {_status, elements} ->
    Enum.map(elements, fn e -> Stack.close(e) end) |> Enum.reverse()
  end)
  |> Enum.map(fn elements ->
    Enum.reduce(elements, 0, fn e, acc -> acc * 5 + Stack.score2(e) end)
  end)
  |> Enum.sort()

Enum.at(values, midPos = div(length(values) - 1, 2))
288957
values =
  input
  |> Enum.map(fn i -> Stack.analyze(i) end)
  |> Enum.filter(fn {status, _char} -> status == :incomplete end)
  |> Enum.map(fn {_status, elements} ->
    Enum.map(elements, fn e -> Stack.close(e) end) |> Enum.reverse()
  end)
  |> Enum.map(fn elements ->
    Enum.reduce(elements, 0, fn e, acc -> acc * 5 + Stack.score2(e) end)
  end)
  |> Enum.sort()

Enum.at(values, midPos = div(length(values) - 1, 2))
3654963618

Correct: 3654963618