From 3ba214f6891712bdc9b264442cec3858f1abcce7 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Tue, 21 Dec 2021 12:02:51 +0200 Subject: Day 21 --- day21/part1.hs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 day21/part1.hs (limited to 'day21/part1.hs') diff --git a/day21/part1.hs b/day21/part1.hs new file mode 100644 index 0000000..2c60e49 --- /dev/null +++ b/day21/part1.hs @@ -0,0 +1,54 @@ +module Part1 (simulate1, makeState1) where + +import Debug.Trace (traceShow) +import Utils + +data State = State + { positions :: [Int], + scores :: [Int], + die :: Int, + dieRolledTotal :: Int + } + deriving (Show) + +makeState1 = State + +rollDie :: State -> (Int, State) +rollDie prevState = (die prevState, prevState {die = die prevState `mod` 100 + 1}) + +setAtIndex :: Int -> b -> [b] -> [b] +setAtIndex i value lst = zip [0 ..] lst $> map (\(i', value') -> if i == i' then value else value') + +position player state = positions state !! player + +score player state = scores state !! player + +move player prevState = + let (dieRoll1, state1) = rollDie prevState + (dieRoll2, state2) = rollDie state1 + (dieRoll3, state3) = rollDie state2 + state = state3 {dieRolledTotal = dieRolledTotal state3 + 3} + + newPos = (position player state + dieRoll1 + dieRoll2 + dieRoll3 - 1) `mod` 10 + 1 + newScore = score player state + newPos + in state + { positions = setAtIndex player newPos (positions state), + scores = setAtIndex player newScore (scores state) + } + +checkWinCondition state + | (scores state !! 0) >= 1000 = Left (1, scores state !! 1, dieRolledTotal state) + | (scores state !! 1) >= 1000 = Left (0, scores state !! 0, dieRolledTotal state) + | otherwise = Right state + +takeTurn :: Int -> State -> Either (Int, Int, Int) State +takeTurn player state = do + let movedState = move player state + checkWinCondition movedState + +simulate1 state player = + let turnTaken = takeTurn player state + nextPlayer = (player + 1) `mod` 2 + in case turnTaken of + Right newState -> simulate1 newState nextPlayer + Left result -> result -- cgit v1.3