41 lines
1.7 KiB
Haskell
41 lines
1.7 KiB
Haskell
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)
|