aboutsummaryrefslogtreecommitdiffstats
path: root/day21/part2.hs
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2021-12-21 12:02:51 +0200
committerJan Tuomi <jans.tuomi@gmail.com>2021-12-21 13:46:12 +0200
commit3ba214f6891712bdc9b264442cec3858f1abcce7 (patch)
tree0d33e59d831975c1b8729ce4f488f1e4fc743165 /day21/part2.hs
parent8cf112cad7c0a52676a834ec3ac77f3006031c87 (diff)
Day 21
Diffstat (limited to 'day21/part2.hs')
-rw-r--r--day21/part2.hs48
1 files changed, 48 insertions, 0 deletions
diff --git a/day21/part2.hs b/day21/part2.hs
new file mode 100644
index 0000000..926e1e5
--- /dev/null
+++ b/day21/part2.hs
@@ -0,0 +1,48 @@
+module Part2 (makeState2, simulate2) where
+
+import Debug.Trace (traceShow)
+import Utils
+
+-- (position, score)
+type Player = (Int, Int)
+
+type State = (Player, Player)
+
+makeState2 :: Player -> Player -> State
+makeState2 p1 p2 = (p1, p2)
+
+win player state = snd (pick player state) >= 21
+
+pick :: Int -> State -> Player
+pick 0 = fst
+pick 1 = snd
+
+move :: Int -> Int -> (Player, Player) -> State
+move delta player state =
+ let (oldPos, oldScore) = pick player state
+ newPos = (oldPos + delta - 1) `mod` 10 + 1
+ newScore = oldScore + newPos
+ newState = updatePlayer player (newPos, newScore) state
+ in newState
+
+updatePlayer :: Int -> Player -> State -> State
+updatePlayer 0 value (_, other) = (value, other)
+updatePlayer 1 value (other, _) = (other, value)
+
+die = [1, 2, 3]
+
+possible3RollSums = [3 .. 9]
+
+coeffs = [1, 3, 6, 7, 6, 3, 1]
+
+simulate2 :: Int -> ((Int, Int), (Int, Int)) -> Integer
+simulate2 player state
+ | win 0 state = 1
+ | win 1 state = 0
+ | otherwise =
+ let (pos, score) = pick player state
+ nextStates = possible3RollSums $> map (\roll -> move roll player state)
+ nextStatesWithC = zip coeffs nextStates
+ nextPlayer = (player + 1) `mod` 2
+ wins = nextStatesWithC $> map (\(c, nextState) -> c * simulate2 nextPlayer nextState) .> sum
+ in wins