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

2022 Day 2

day_02.livemd

2022 Day 2

Mix.install([:kino])

Input

Run in Livebook

input = Kino.Input.textarea("Puzzle Input")

Code

Module

defmodule RockPaperScissors do
  def total_score(input) do
    input
    |> process_input()
    |> Enum.map(&score/1)
    |> Enum.sum()
  end

  def strategic_score(input) do
    input
    |> process_input()
    |> Enum.map(&strategic/1)
    |> Enum.sum()
  end

  # Convert Letters to Integers
  # Rock: 1, Paper: 2, Scissors: 3
  # or (Part 2) Loss: 1, Draw: 2, Win: 3
  defp numerize(char) when char in ["A", "X"], do: 1
  defp numerize(char) when char in ["B", "Y"], do: 2
  defp numerize(char) when char in ["C", "Z"], do: 3

  # draw
  defp score([num, num]), do: 3 + num
  # win
  defp score([3, 1]), do: 7
  defp score([1, 2]), do: 8
  defp score([2, 3]), do: 9
  # loss
  defp score([_, num]), do: num

  # loss
  defp strategic([1, 1]), do: 3
  defp strategic([them, 1]), do: them - 1
  # draw
  defp strategic([them, 2]), do: them + 3
  # win
  defp strategic([3, 3]), do: 7
  defp strategic([them, 3]), do: them + 7

  defp process_input(input) do
    input
    |> String.split()
    |> Enum.map(&numerize/1)
    |> Enum.chunk_every(2)
  end
end

Evaluate

part_1 =
  input
  |> Kino.Input.read()
  |> RockPaperScissors.total_score()

part_2 =
  input
  |> Kino.Input.read()
  |> RockPaperScissors.strategic_score()

{part_1, part_2}

Test

ExUnit.start(autorun: false)

defmodule RockPaperScissorsTest do
  use ExUnit.Case, async: true

  setup do
    input = ~s(
A Y
B X
C Z
)

    {:ok, input: input}
  end

  test "total_score", %{input: input} do
    assert RockPaperScissors.total_score(input) == 15
  end

  test "strategic_score", %{input: input} do
    assert RockPaperScissors.strategic_score(input) == 12
  end
end

ExUnit.run()