Serguey Zefirov (thesz) wrote,

Выпил пива с мёдом, поскольку температура 37,1...

,,,и написал Игру Жизнь:
import qualified Data.Map as Map
import qualified Data.Set as Set

type LifeField = Set.Set (Int,Int)

lifeStep :: LifeField -> LifeField
lifeStep start = next
	where
		occupied = Set.toList start
		expandNeighbour (y,x) = [Map.singleton (j,i) 1
			| i <- [x-1 .. x+1]
			, j <- [y-1 .. y+1]
			, i /= x || j /= y]
		expandedNeighbours = concatMap expandNeighbour occupied
		neighbours = Map.unionsWith (+) expandedNeighbours
		nbCount xy = Map.findWithDefault 0 xy neighbours
		die n = n < 2 || n > 3
		withoutDead = Set.filter (not . die . nbCount) start
		newborn = Map.keysSet $ Map.filter (==3) neighbours
		next = Set.union withoutDead newborn

display field
	| Set.null field = ["."]
	| otherwise = lines
	where
		xs = map snd $ Set.toList field
		ys = map fst $ Set.toList field
		xMin = minimum xs
		yMin = minimum ys
		xMax = maximum xs
		yMax = maximum ys
		risen x y = Set.member (y,x) field
		row y = [if risen x y then '*' else '.' | x <- [xMin..xMax]]
		lines = map row [yMin..yMax]

fromLines :: [String] -> LifeField
fromLines lines = Set.fromList $ 
	map fst $ filter snd $ concat $ zipWith fromLine [0..] lines
	where
		fromLine y cs = zipWith (fromChar y) [0..] cs
		fromChar y x '*' = ((y,x),True)
		fromChar y x _ = ((y,x),False)

lifeSteps field n
	| n > 0 = do
		mapM putStrLn $ display field
		putStrLn (replicate 10 '-')
		lifeSteps (lifeStep field) (n-1)
	| otherwise = do
		putStrLn $ "Field inhabitants count: "++show (Set.size field)
		return ()

gliders = fromLines [
	 "........................"
	,"....***.......***......."
	,"....*...........*......."
	,".....*.........*........"
	,".........*.............."
	,".........*.............."
	,".........*.............."
	,".....*.........*........"
	,"....*...........*......."
	,"....***.......***......."
	,"........................"
	]


Запуск в ghci 'lifeSteps gliders 100', например.

Всё написано оптимальным образом: память требуется только под живые клетки.

Ради прикола. И ради спора в rsug. ;)
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 25 comments