Created
December 28, 2018 17:21
-
-
Save 3v0k4/57bf37be74bf7ffe9aa41c8e736e2f1a to your computer and use it in GitHub Desktop.
AdventOfCode 2018 PureScript - Day 9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module Main where | |
| import Prelude | |
| import Effect (Effect) | |
| import Effect.Console (logShow) | |
| import RRBList ((!!), length, insertAt, deleteAt, singleton) | |
| import RRBList.Types (List) | |
| import Data.Foldable (maximumBy) | |
| import Data.Maybe (Maybe(..), fromJust) | |
| import Math ((%)) | |
| import Data.Int (rem, toNumber, floor) | |
| import Data.Map (Map, empty, insert, lookup, toUnfoldable) | |
| import Partial.Unsafe (unsafePartial) | |
| import Data.Tuple (Tuple, snd) | |
| import Data.Function (on) | |
| import Data.Int53 (Int53, fromInt) | |
| nPlayers :: Int | |
| nPlayers = 477 | |
| type Game = | |
| { index :: Int | |
| , marbles :: List Int | |
| , scores :: Map Int Int53 | |
| } | |
| init :: Game | |
| init = | |
| { index: 0 | |
| , marbles: singleton 0 | |
| , scores: empty | |
| } | |
| insertMarble :: Int -> Game -> Game | |
| insertMarble marble game | |
| | marble `isMultipleOf` 23 = insertMarbleMult marble game | |
| | otherwise = insertMarbleNonMult marble game | |
| insertMarbleMult :: Int -> Game -> Game | |
| insertMarbleMult marble game@{ marbles, index, scores } = | |
| game { marbles = newMarbles, index = newIndex, scores = newScores } | |
| where newIndex = calculateIndex marbles (index - 7) | |
| newMarbles = unsafePartial fromJust (deleteAt newIndex marbles) | |
| player = marble `rem` nPlayers | |
| points = marble + (unsafePartial fromJust (marbles !! newIndex)) | |
| newScores = updateScores player points scores | |
| insertMarbleNonMult :: Int -> Game -> Game | |
| insertMarbleNonMult marble game@{ marbles, index, scores } = | |
| game { marbles = newMarbles, index = newIndex } | |
| where newIndex = calculateIndex marbles (index + 2) | |
| newMarbles = unsafePartial fromJust $ insertAt newIndex marble marbles | |
| calculateIndex :: forall a. List a -> Int -> Int | |
| calculateIndex xs i = | |
| floor $ toNumber (l + (floor (toNumber i % toNumber l))) % toNumber l | |
| where l = length xs | |
| isMultipleOf :: Int -> Int -> Boolean | |
| isMultipleOf x y = toNumber x % toNumber y == 0.0 | |
| updateScores :: Int -> Int -> Map Int Int53 -> Map Int Int53 | |
| updateScores player points scores = | |
| case lookup player scores of | |
| Just v -> insert player (v + fromInt points) scores | |
| Nothing -> insert player (fromInt points) scores | |
| playTurn :: Int -> Int -> Game -> Maybe (Tuple Int Int53) | |
| playTurn maxMarble n game | |
| | n == maxMarble - 1 = maximumBy (compare `on` snd) (toUnfoldable game.scores :: List (Tuple Int Int53)) | |
| | otherwise = playTurn maxMarble (n + 1) (insertMarble n game) | |
| main :: Effect Unit | |
| main = do | |
| logShow $ playTurn 70851 1 init | |
| logShow $ playTurn 7085100 1 init |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment