module Main where import Utils import Data.List (sortOn) import Data.Map (Map, (!)) import qualified Data.Map as Map import Data.Maybe dirs = [ (-1,-1), (0,-1), (1,-1) , (-1, 0), (1, 0) , (-1, 1), (0, 1), (1, 1) ] adjs1 m pt = howMany (== '#') $ mapMaybe ((`Map.lookup` m) . add pt) dirs inGrid (x, y) w h = x < w && x >= 0 && y < h && y >= 0 adjs2 grid pt w h = howMany ((== '#') . head) $ filter (not . null) $ map (dropWhile (== '.') . map (grid !) . takeWhile (inside (0, 0) (w-1, h-1)) . map ($ pt) . repeatF . add) dirs rule1 w h m pt@(x, y) = if as == 0 then '#' else 'L' where as = adjs2 m pt w h rule2 w h m pt@(x, y) = if as >= 5 then 'L' else '#' where as = adjs2 m pt w h doStep w h m = Map.mapWithKey fn m where fn k 'L' = rule1 w h m k fn k '#' = rule2 w h m k fn k '.' = '.' stepWhile prev w h | prev == next = next | otherwise = stepWhile next w h where next = doStep w h prev main :: IO () main = do n <- readFile "input/11" let (grid, width, height) = makeGrid n let solve1 = stepWhile grid width height print $ howMany ((== '#') . snd) $ Map.toList solve1