input = Kino.Input.textarea("Puzzle Input")
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
part_1 =
input
|> Kino.Input.read()
|> RockPaperScissors.total_score()
part_2 =
input
|> Kino.Input.read()
|> RockPaperScissors.strategic_score()
{part_1, part_2}
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()