diff --git a/2022/src/days/day_2.gleam b/2022/src/days/day_2.gleam index dde9773..e92b951 100644 --- a/2022/src/days/day_2.gleam +++ b/2022/src/days/day_2.gleam @@ -8,9 +8,18 @@ type Hand { Scissors } +type Outcome { + Lose + Draw + Win +} + type Game = #(Hand, Hand) +type RiggedGame = + #(Hand, Outcome) + pub fn pt_1(input: String) -> Int { string.split(input, on: "\n") |> list.map(parse_line) @@ -18,8 +27,12 @@ pub fn pt_1(input: String) -> Int { |> int.sum } -pub fn pt_2(_input: String) -> Int { - todo +pub fn pt_2(input: String) -> Int { + string.split(input, on: "\n") + |> list.map(parse_line_pt2) + |> list.map(generate_hand) + |> list.map(score_game) + |> int.sum } fn parse_line(line: String) -> Game { @@ -27,6 +40,11 @@ fn parse_line(line: String) -> Game { #(to_hand(a), to_hand(b)) } +fn parse_line_pt2(line: String) -> RiggedGame { + assert [a, b] = string.split(line, on: " ") + #(to_hand(a), to_outcome(b)) +} + fn to_hand(raw: String) -> Hand { case raw { "A" -> Rock @@ -38,6 +56,17 @@ fn to_hand(raw: String) -> Hand { } } +// X means you need to lose, +// Y means you need to end the round in a draw, +// and Z means you need to win. +fn to_outcome(raw: String) -> Outcome { + case raw { + "X" -> Lose + "Y" -> Draw + "Z" -> Win + } +} + fn score_game(game: Game) -> Int { let score = case game { // (them, me) @@ -61,3 +90,16 @@ fn score_hand(hand: Hand) -> Int { Scissors -> 3 } } + +/// Determine the hand to play give the opponent's hand and desired outcome +fn generate_hand(game: RiggedGame) -> Game { + case game { + #(Rock, Lose) -> #(Rock, Scissors) + #(Rock, Win) -> #(Rock, Paper) + #(Paper, Lose) -> #(Paper, Rock) + #(Paper, Win) -> #(Paper, Scissors) + #(Scissors, Lose) -> #(Scissors, Paper) + #(Scissors, Win) -> #(Scissors, Rock) + #(_, Draw) -> #(game.0, game.0) + } +}