summaryrefslogtreecommitdiff
path: root/2017/6.hs
blob: d4390ab3075f68f0afd68168bb317d2312da3be2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import Control.Monad
import Data.List
import qualified Data.Map.Strict as Map


modifyAt :: Show a => Int -> (a -> a) -> [a] -> [a]
modifyAt i f l =
    let (pre, v : post) = splitAt i l
    in pre ++ f v : post

redistribute :: [Int] -> [Int]
redistribute blocks =
    let Just idx = findIndex (== maximum blocks) blocks
        amt = blocks !! idx
        len = length blocks
        spread _ 0 b = b
        spread i a b = spread (succ i `mod` len) (pred a) (modifyAt i succ b)
    in spread (succ idx `mod` len) amt (modifyAt idx (const 0) blocks)

cycledetect :: [Int] -> (Int, Int)
cycledetect blocks = go Map.empty 0 blocks
  where
    go mp idx bl = case Map.lookup bl mp of
        Nothing -> go (Map.insert bl idx mp) (succ idx) (redistribute bl)
        Just i -> (idx, idx - i)

main :: IO ()
main = do
    blocks <- liftM (map read . words) (readFile "6.in")
    let (q1, q2) = cycledetect blocks
    print q1
    print q2