module Commons where import GHC.IO.Handle (isEOF) import Data.Array (Array, listArray, bounds, (!), (//)) data Tile = Empty | Round | Square deriving (Eq, Show) type Platform = Array (Int, Int) Tile parseLine :: String -> [Tile] parseLine [] = [] parseLine ('O': t) = Round: parseLine t parseLine ('#': t) = Square: parseLine t parseLine ('.': t) = Empty: parseLine t parsePlatform :: IO [[Tile]] parsePlatform = do done <- isEOF if done then return [] else do line <- getLine let platformLine = parseLine line platform <- parsePlatform return (platformLine: platform) parse :: IO Platform parse = do platform <- parsePlatform return (listArray ((1, 1), (length platform, length $ head platform)) $ concat platform) tilt :: (Int, Int) -> [(Int, Int)] -> Platform -> Platform tilt _ [] platform = platform tilt (yI, xI) ((y, x): t) platform | let (y2, x2) = (y + yI, x + xI) in y2 > 0 && y2 <= fst (snd $ bounds platform) && x2 > 0 && x2 <= snd (snd $ bounds platform) && platform ! (y2, x2) == Empty = tilt (yI, xI) ((y + yI, x + xI): t) $ platform // [((y, x), Empty)] | otherwise = tilt (yI, xI) t $ platform // [((y, x), Round)]