호두나무 공방/Advent of Code

Advent of Code 2021 Day 2 in Elixir - Dive!

2021. 12. 2. 22:09

'위, 아래, 전진' 커맨드를 받아 처리한 뒤 잠수함의 최종 위치를 계산하는 문제였다. 아직 어렵지는 않지만 본격적으로 시작하기 전에 약간 드릉드릉 하는 느낌이 있다. 커맨드를 받아 처리한 뒤의 결과를 계산하는 문제는 경험상 확장할 여지가 많아(새 명령어를 추가한다든가... 당장 이번의 두 번째 문제도 처리법을 바꿨을 때의 달라진 결과를 계산하는 문제였고) 앞으로 한두 번쯤은 이 문제를 레퍼런스하는 일이 있을 것 같다.

defmodule Day2 do
  def parse_input do
    path = "input/day2.txt"

    File.read!(path)
    |> String.split("\n")
    |> Enum.map(&parse_command/1)
  end

  # command = "forward 1", "down 2", "up 3", ...
  defp parse_command(command) do
    command
    |> String.split(" ")
    |> List.update_at(1, &String.to_integer/1)
    |> List.to_tuple()
  end

  def run_q1 do
    parse_input()
    |> Enum.reduce({0, 0}, fn
      {"forward", n}, {position, depth} ->
        {position + n, depth}

      {"down", n}, {position, depth} ->
        {position, depth + n}

      {"up", n}, {position, depth} ->
        {position, depth - n}
    end)
    |> then(fn {position, depth} ->
      position * depth
    end)
  end

  def run_q2 do
    parse_input()
    |> Enum.reduce({0, 0, 0}, fn
      {"forward", n}, {position, depth, aim} ->
        {position + n, depth + (n * aim), aim}

      {"down", n}, {position, depth, aim} ->
        {position, depth, aim + n}

      {"up", n}, {position, depth, aim} ->
        {position, depth, aim - n}
    end)
    |> then(fn {position, depth, _aim} ->
      position * depth
    end)
  end
end