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

Day 2: Rock Paper Scissors

2022/day-02.livemd

Day 2: Rock Paper Scissors

Mix.install([{:kino, "~> 0.7.0"}])

Day 2

I really should have put together some mathematical equivalences instead of translating manually between strings and atoms everywhere and using matching for the logic… :|

Maybe I’ll revisit or just do better next time.

sample_input = Kino.Input.textarea("Paste Sample Input")
real_input = Kino.Input.textarea("Paste Real Input")
normalize = fn
  "A" -> :rock
  "B" -> :paper
  "C" -> :scissors
  "X" -> :rock
  "Y" -> :paper
  "Z" -> :scissors
end

outcome_score = fn
  {same, same} -> 3
  {:rock, :paper} -> 6
  {:paper, :scissors} -> 6
  {:scissors, :rock} -> 6
  _ -> 0
end

choice_score = fn
  {_, :rock} -> 1
  {_, :paper} -> 2
  _ -> 3
end

round_score = fn raw_round ->
  [opponent, me] = String.split(raw_round)
  round = {normalize.(opponent), normalize.(me)}
  outcome_score.(round) + choice_score.(round)
end

total_score = fn input ->
  input
  |> Kino.Input.read()
  |> String.split("\n")
  |> Enum.map(round_score)
  |> Enum.sum()
end
total_score.(sample_input)
total_score.(real_input)
my_play = fn
  opponent_play, "Y" -> opponent_play
  :rock, "Z" -> :paper
  :rock, "X" -> :scissors
  :paper, "Z" -> :scissors
  :paper, "X" -> :rock
  :scissors, "Z" -> :rock
  :scissors, "X" -> :paper
end

parse_round_2 = fn raw_round ->
  [opponent, instruction] = String.split(raw_round)
  opponent_play = normalize.(opponent)
  {opponent_play, my_play.(opponent_play, instruction)}
end

round_score_2 = fn round ->
  outcome_score.(round) + choice_score.(round)
end

total_score_2 = fn input ->
  input
  |> Kino.Input.read()
  |> String.split("\n")
  |> Enum.map(parse_round_2)
  |> Enum.map(round_score_2)
  |> Enum.sum()
  |> dbg()
end
total_score_2.(sample_input)
total_score_2.(real_input)