module Part2 where import Commons import Data.Array (bounds, assocs) import Data.List (sortBy, elemIndices) tiltNorth :: Platform -> Platform tiltNorth platform = tilt (-1, 0) (map fst $ filter (\ (_, r) -> r == Round) $ assocs platform) platform tiltWest :: Platform -> Platform tiltWest platform = tilt (0, -1) (sortBy (\ (y1, x1) (y2, x2) -> if x1 < x2 then LT else GT) $ map fst $ filter (\ (_, r) -> r == Round) $ assocs platform) platform tiltSouth :: Platform -> Platform tiltSouth platform = tilt (1, 0) (reverse $ map fst $ filter (\ (_, r) -> r == Round) $ assocs platform) platform tiltEast :: Platform -> Platform tiltEast platform = tilt (0, 1) (sortBy (\ (y1, x1) (y2, x2) -> if x1 > x2 then LT else GT) $ map fst $ filter (\ (_, r) -> r == Round) $ assocs platform) platform applyCycles :: [Platform] -> Platform -> [Platform] applyCycles history platform | history /= [] && platform `elem` tail history = history | otherwise = let newPlatform = tiltEast $ tiltSouth $ tiltWest $ tiltNorth platform in applyCycles (newPlatform: history) newPlatform getExpectedIndex :: [Platform] -> Int getExpectedIndex history = let endIndex = length history startIndex = endIndex - last (elemIndices (head history) history) in endIndex - (((1000000000 - startIndex) `mod` (endIndex - startIndex)) + startIndex) getLoads :: Platform -> [Int] getLoads platform = let (yMax, _) = snd $ bounds platform cyclesHistory = applyCycles [] platform in map (\ ((y, _), r) -> if r == Round then yMax + 1 - y else 0) $ assocs (cyclesHistory !! getExpectedIndex cyclesHistory)