X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=src%2Fadvent17%2Fadvent17.hs;fp=src%2Fadvent17%2Fadvent17.hs;h=edbfd85e5505d46ecf84db9acec998a104b760c0;hb=9ce2b21f9734aa6e51186d2cc0075083a5864155;hp=0000000000000000000000000000000000000000;hpb=fc23edeb0e66a61d640dfeaffd5a274a63acf8c8;p=advent-of-code-17.git diff --git a/src/advent17/advent17.hs b/src/advent17/advent17.hs new file mode 100644 index 0000000..edbfd85 --- /dev/null +++ b/src/advent17/advent17.hs @@ -0,0 +1,72 @@ +{-# LANGUAGE NegativeLiterals #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE NegativeLiterals #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE BangPatterns #-} + +-- import Prelude hiding ((++)) +import Data.Vector.Unboxed ((!)) +import qualified Data.Vector.Unboxed as V +import Data.List (foldl') + +type RingBuffer = V.Vector Int + +initialStepSize :: Int +initialStepSize = 366 + +initialRingBuffer :: RingBuffer +initialRingBuffer = V.singleton 0 + + +main :: IO () +main = do + print $ part1 2017 + -- print $ part2 50000000 + print $ ith 2017 366 + print $ oneth 50000000 366 + + + +part1 :: Int -> Int +part1 k = (!1) $ (iterate updateRingBuffer initialRingBuffer)!!k + +part2 :: Int -> Int +part2 k = finalBuffer!targetLoc + where finalBuffer = (iterate updateRingBuffer initialRingBuffer)!!k + zeroLoc = V.head $ V.elemIndices 0 finalBuffer + targetLoc = (zeroLoc + 1) `rem` (V.length finalBuffer) + +updateRingBuffer :: RingBuffer -> RingBuffer +updateRingBuffer buffer = buffer' + where nextPos = (initialStepSize + 1) `rem` V.length buffer + (start, end) = V.splitAt nextPos buffer + nextValue = V.length buffer + buffer' = V.cons nextValue $ (V.++) end start + + + +(%) = mod + +ith :: Int -> Int -> Int +ith i steps = + let (position, list) = foldl' (\(currPos, currList) n -> + let newPos = (currPos + steps % n + 1) % n + in (newPos, take newPos currList ++ [n] ++ drop newPos currList)) + (0, [0]) [1..i] + in list !! (position + 1) + +oneth :: Int -> Int -> Int +oneth i steps = + snd $ foldl' (\(currPos, currOneth) n -> + let !newPos = (currPos + steps % n + 1) % n + in (newPos, if newPos == 0 then n else currOneth)) + (0, 1) [1..i] + +-- main :: IO () +-- main = do +-- print $ ith 2017 312 +-- print $ oneth 50000000 312 \ No newline at end of file