module Main where import Control.Monad import Data.Map (Map) import qualified Data.Map as Map import Data.Maybe import Utils type Pos = (Int, Int, Int, Int) toBool '#' = True toBool '.' = False gridMap :: String -> Map Pos Bool gridMap s = Map.fromList [((x,y,0,0), toBool a) | (y, row) <- zip [0..] rows , (x, a) <- zip [0..] row ] where rows = lines s around :: Pos -> [Pos] around (x,y,z,w) = [(x+x', y+y', z+z', w+w') | x' <- [-1..1] , y' <- [-1..1] , z' <- [-1..1] , w' <- [-1..1] , (x',y',z',w') /= (0,0,0,0) ] convert True 2 = True convert True 3 = True convert False 3 = True convert _ _ = False doStep :: Map Pos Bool -> Map Pos Bool doStep m = Map.mapWithKey fn $ m <> Map.fromList [(p, False) | p <- concatMap around (Map.keys m)] where fn pos v = convert v n where n = howMany id $ map (fromMaybe False . flip Map.lookup m) $ around pos main :: IO () main = do n <- readFile "input/17" let grid = gridMap n print $ Map.size $ Map.filter id (iterate doStep grid !! 6)