width :: Int width = 100 width2 :: Int width2 = width + 2 golStep :: [[Int]] -> [[Int]] golStep bd = replicate width2 0 : (map golLine $ zip [1..] $ init (tail bd)) ++ [replicate width2 0] where golLine (y,l) = map (golCell y) $ zip [0..] l golCell y (x,c) = if x == 0 || x == width2 - 1 then 0 else if golSum x y == 3 || (c == 1 && golSum x y == 2) then 1 else 0 golSum x y = bd!!(y-1)!!(x-1)+ bd!!(y-1)!!(x )+ bd!!(y-1)!!(x+1)+ bd!!(y )!!(x+1)+ bd!!(y+1)!!(x+1)+ bd!!(y+1)!!(x )+ bd!!(y+1)!!(x-1)+ bd!!(y )!!(x-1) setCorners :: [[Int]] -> [[Int]] setCorners bd = bd!!0 : set2 (bd!!1) : (init $ init $ drop 2 bd) ++ [set2 (bd!!(width2-2)),last bd] where set2 line = head line : 1 : (init $ init $ drop 2 line) ++ [1,last line] day18 :: IO () day18 = do input <- readFile "day18.txt" let bd = map (\l -> 0 : l ++ [0]) $ replicate width 0 : [map (\c -> if c == '#' then 1 else 0) l | l <- lines input] ++ [replicate width 0] print $ sum $ map sum $ iterate (setCorners . golStep) bd !! 100 -- part 1: setCorners -> id main = day18