Skip to content

Instantly share code, notes, and snippets.

@tfausak
Last active December 16, 2020 00:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tfausak/f31c36ddc006a7ad42fc098ddd0fb40b to your computer and use it in GitHub Desktop.
Save tfausak/f31c36ddc006a7ad42fc098ddd0fb40b to your computer and use it in GitHub Desktop.
import qualified Data.IntMap as IntMap
import qualified Data.List as List
import qualified Data.Maybe as Maybe
import qualified Data.Ord as Ord
import qualified Data.Text as Text
main = do
print limit
interact
$ show
. playGame
. IntMap.fromList
. fmap (\ ( index, number ) -> ( number, ( index + 1, Nothing ) ))
. zip [ 0 .. ]
. fmap (read . Text.unpack)
. Text.splitOn (Text.singleton ',')
. Text.strip
. Text.pack
playGame :: IntMap.IntMap ( Int, Maybe Int ) -> Maybe Int
playGame seen = do
( number, ( turn, _ ) ) <- maximumOn snd $ IntMap.toList seen
pure $ takeTurn number (turn + 1) seen
maximumOn :: Ord b => (a -> b) -> [ a ] -> Maybe a
maximumOn f = Maybe.listToMaybe . List.sortOn (Ord.Down . f)
takeTurn :: Int -> Int -> IntMap.IntMap ( Int, Maybe Int ) -> Int
takeTurn number turn seen =
let
nextNumber = case IntMap.lookup number seen of
Just ( x, Just y ) -> x - y
_ -> 0
nextSeen = IntMap.alter (\ m -> Just ( turn, fmap fst m )) nextNumber seen
in if turn > limit then number else takeTurn nextNumber (turn + 1) nextSeen
limit :: Int
limit = 30000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment