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

Advent of Code 2022 - Day 2

aoc2022-02.livemd

Advent of Code 2022 - Day 2

Puzzle description

Day 2: Rock Paper Scissors.

Input

defmodule Input do
  def load! do
    "input/02.txt"
    |> Path.expand(__DIR__)
    |> File.stream!()
  end

  @doc """
  Returns normalized output when generating streams from files or string input.
  """
  def to_stream(input) when is_binary(input) do
    input
    |> String.trim("\n")
    |> String.splitter("\n")
  end

  def to_stream(stream) do
    stream
    |> Stream.map(fn string -> String.trim_trailing(string, "\n") end)
  end

  def debug(stream) do
    stream |> Enum.into([]) |> dbg()
    stream
  end
end

Solution

defmodule Part1 do
  # preflight:
  ## split string into lines (without break characters)
  def run(input) do
    input
    |> Stream.map(&check/1)
    |> Enum.into([])
    |> Enum.sum()
  end

  # Rocks:      A X
  # Papers:     B Y
  # Scissorses: C Z

  # W: 6
  # D: 3
  # L: 0

  # rock / rock, D
  def check("A X"), do: 4

  # rock / paper, W
  def check("A Y"), do: 8

  # rock / scissors, L
  def check("A Z"), do: 3

  # paper / rock, L
  def check("B X"), do: 1

  # paper / paper, D
  def check("B Y"), do: 5

  # paper / scissors, W
  def check("B Z"), do: 9

  # scissors / rock, W
  def check("C X"), do: 7

  # scissors / paper, L
  def check("C Y"), do: 2

  # scissors / scissors, D
  def check("C Z"), do: 6
end

defmodule Part2 do
  # preflight:
  ## split string into lines (without break characters)
  def run(input) do
    input
    |> Stream.map(&check/1)
    |> Enum.into([])
    |> Enum.sum()
  end

  # rock / L, choose scissors
  def check("A X"), do: 3

  # rock / D, choose rock
  def check("A Y"), do: 4

  # rock / W, choose paper
  def check("A Z"), do: 8

  # paper / L, choose rock
  def check("B X"), do: 1

  # paper / D, choose paper
  def check("B Y"), do: 5

  # paper / W, choose: scissors
  def check("B Z"), do: 9

  # scissors / L, choose: paper
  def check("C X"), do: 2

  # scissors / D, choose: scissors
  def check("C Y"), do: 6

  # scissors / W, choose: rock
  def check("C Z"), do: 7
end

ExUnit.start(autorun: false)

defmodule Test do
  use ExUnit.Case, async: true
  @example_input ~s(
A Y
B X
C Z
)

  @input Input.load!()

  test "part 1" do
    assert @example_input |> Input.to_stream() |> Part1.run() === 15

    @input |> Input.to_stream() |> Part1.run() |> dbg()
  end

  test "part 2" do
    assert @example_input |> Input.to_stream() |> Part2.run() === 12

    @input |> Input.to_stream() |> Part2.run() |> dbg()
  end
end

ExUnit.configure(trace: true)
ExUnit.run()