Name: Anonymous 2007-09-08 12:44 ID:fuIqtYYp
import qualified Data.Map as M
type Location = (Int,Int)
main = renderloop [(1,2),(2,3),(3,1),(3,2),(3,3)]
where renderloop = mapM_ (\v -> render 20 v >> getLine) . iterate count
count :: [Location] -> [Location]
count locs = M.keys live ++ [v| v <-locs, M.member v still]
where neighborCount = foldl foldFun M.empty . concatMap allNeighbors
(live,still) = M.partition (== 3) . M.filter (`elem` [2,3]) . neighborCount $ locs
foldFun :: M.Map Location Int -> Location -> M.Map Location Int
foldFun map loc = M.insertWith (+) loc 1 map
allNeighbors :: Location -> [Location]
allNeighbors (x,y) = [(nx,ny) | nx <- [x+1,x-1,x], ny <- [y+1,y-1,y], (x,y) /= (nx,ny) ]
render size locs = mapM_ (putStrLn . makeRow locs size) (reverse [0..size])
makeRow locs wid r = map (\x -> if x `elem` inds then '#' else '.') [0..wid]
where inds = [j | (p,j) <- locs, p == r]:)