From ac5fd19a42e1a364301e645998d06b7d695d0b9f Mon Sep 17 00:00:00 2001 From: Sloane Perrault Date: Wed, 21 Sep 2022 09:19:54 -0400 Subject: [PATCH] 2021 day 21 --- 2021/README.md | 4 +++- 2021/lib/2021/21.ex | 47 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/2021/README.md b/2021/README.md index df2fac9..a82dfd9 100644 --- a/2021/README.md +++ b/2021/README.md @@ -17,7 +17,7 @@ | | | | [1] | [2] | [3] | [4] | | [5] | [6] | [7] | [8] | [9] | [10] | [11]| | [12]| [13]| [14]| [15] | [16] | [17] | [18] | -| [19] | 20 | 21 | 22 | 23 | 24 | 25 | +| [19] | 20 | [21] | 22 | 23 | 24 | 25 | @@ -40,3 +40,5 @@ [17]: ./lib/2021/17.ex [18]: ./lib/2021/18.ex [19]: ./lib/2021/19.ex + +[21]: ./lib/2021/21.ex diff --git a/2021/lib/2021/21.ex b/2021/lib/2021/21.ex index 498f2bd..6cc9c52 100644 --- a/2021/lib/2021/21.ex +++ b/2021/lib/2021/21.ex @@ -11,8 +11,52 @@ aoc 2021, 21 do end def p2 do + input_players() + |> run_dirac_dice_game() + |> Tuple.to_list() + |> Enum.max() end + @dirac_dice_winning_score 21 + @quantum_rolls %{ 3 => 1, 4 => 3, 5 => 6, 6 => 7, 7 => 6, 8 => 3, 9 => 1 } + + def run_dirac_dice_game(players, up_to_play \\ :player_1) + def run_dirac_dice_game({{_, player_1_score}, _}, :player_2) when player_1_score >= @dirac_dice_winning_score, do: {1, 0} + def run_dirac_dice_game({_, {_, player_2_score}}, :player_1) when player_2_score >= @dirac_dice_winning_score, do: {0, 1} + + def run_dirac_dice_game({player_1, player_2}, :player_1) do + for {player_1, freq} <- quantum_move(player_1) do + run_dirac_dice_game({player_1, player_2}, :player_2) + |> multiply_by(freq) + |> compact() + end + |> compact() + end + + def run_dirac_dice_game({player_1, player_2}, :player_2) do + for {player_2, freq} <- quantum_move(player_2) do + run_dirac_dice_game({player_1, player_2}, :player_1) + |> multiply_by(freq) + |> compact() + end + |> compact() + end + + def quantum_move(player) do + for {roll, freq} <- @quantum_rolls do + {move(player, roll), freq} + end + end + + def multiply_by(xs, c) when is_list(xs), do: Enum.map(xs, &multiply_by(&1, c)) + def multiply_by({a, b}, c), do: {a * c, b * c} + + def compact(xs) when is_list(xs) do + {as, bs} = Enum.unzip(xs) + {Enum.sum(as), Enum.sum(bs)} + end + def compact(tp) when is_tuple(tp), do: tp + def play_game(players, die, winning_score \\ 1000) do Enum.reduce_while(rolls(die), {0, players}, fn roll, {roll_count, {player, other_player}} -> @@ -24,8 +68,9 @@ aoc 2021, 21 do end) end + def move(player, rolls) when is_list(rolls), do: move(player, Enum.sum(rolls)) def move({position, score}, roll) do - position = (position + Enum.sum(roll)) |> to_board_position() + position = to_board_position(position + roll) score = score + position {position, score}