diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2021-12-21 12:02:51 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2021-12-21 13:46:12 +0200 |
| commit | 3ba214f6891712bdc9b264442cec3858f1abcce7 (patch) | |
| tree | 0d33e59d831975c1b8729ce4f488f1e4fc743165 /day21/part1.hs | |
| parent | 8cf112cad7c0a52676a834ec3ac77f3006031c87 (diff) | |
Day 21
Diffstat (limited to 'day21/part1.hs')
| -rw-r--r-- | day21/part1.hs | 54 |
1 files changed, 54 insertions, 0 deletions
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 |
