aoc2022/day2.livemd
2022-12-11 23:02:26 +01:00

3.2 KiB

AOC 2022 - Day 2

Mix.install([
  {:req, "~> 0.3.3"}
])

Puzzle description

Day 2: Rock Paper Scissors.

Input

defmodule Load do
  def input do
    aoc_session = System.fetch_env!("LB_AOC_SESSION")
    input_url = "https://adventofcode.com/2022/day/2/input"
    Req.get!(input_url, headers: [cookie: "session=#{aoc_session}"]).body
  end
end

Solution

defmodule Util do
  def process(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(fn entry ->
      entry
      |> String.split()
      |> Enum.map(fn
        symbol when symbol in ["A", "X"] -> :rock
        symbol when symbol in ["B", "Y"] -> :paper
        symbol when symbol in ["C", "Z"] -> :scissors
      end)
    end)
  end

  def process2(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(fn entry ->
      entry
      |> String.split()
      |> Enum.map(fn
        "A" -> :rock
        "B" -> :paper
        "C" -> :scissors
        "X" -> :lose
        "Y" -> :draw
        "Z" -> :win
      end)
    end)
  end

  # Check your opponent vs you
  def check_pair(:rock, :rock), do: :draw
  def check_pair(:rock, :paper), do: :win
  def check_pair(:rock, :scissors), do: :lose
  def check_pair(:paper, :rock), do: :lose
  def check_pair(:paper, :paper), do: :draw
  def check_pair(:paper, :scissors), do: :win
  def check_pair(:scissors, :rock), do: :win
  def check_pair(:scissors, :paper), do: :lose
  def check_pair(:scissors, :scissors), do: :draw

  # Check reverse
  def check_pair(:rock, :lose), do: :scissors
  def check_pair(:rock, :draw), do: :rock
  def check_pair(:rock, :win), do: :paper
  def check_pair(:paper, :lose), do: :rock
  def check_pair(:paper, :draw), do: :paper
  def check_pair(:paper, :win), do: :scissors
  def check_pair(:scissors, :lose), do: :paper
  def check_pair(:scissors, :draw), do: :scissors
  def check_pair(:scissors, :win), do: :rock

  def points(:win), do: 6
  def points(:draw), do: 3
  def points(:lose), do: 0
  def points(:rock), do: 1
  def points(:paper), do: 2
  def points(:scissors), do: 3
end
defmodule Part1 do
  def run(input) do
    Util.process(input)
    |> Enum.map(fn [they, you] -> {you, Util.check_pair(they, you)} end)
    |> Enum.map(fn {played, result} -> Util.points(played) + Util.points(result) end)
    |> Enum.sum()
  end
end

defmodule Part2 do
  def run(input) do
    Util.process2(input)
    |> Enum.map(fn [they, you] -> {you, Util.check_pair(they, you)} end)
    |> Enum.map(fn {played, result} -> Util.points(played) + Util.points(result) end)
    |> Enum.sum()
  end
end

ExUnit.start(autorun: false)

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

  test "it loads the input" do
    assert String.length(@input) > 0
  end

  test "part 1 example" do
    assert Part1.run(@example_input) === 15
  end

  test "part 1" do
    assert Part1.run(@input) === 13052
  end

  test "part 2 example" do
    assert Part2.run(@example_input) === 12
  end

  test "part 2" do
    assert Part2.run(@input) === 13693
  end
end

ExUnit.run()