29 lines
901 B
Haskell
29 lines
901 B
Haskell
|
module Conway
|
||
|
( Index(..)
|
||
|
, update
|
||
|
)
|
||
|
where
|
||
|
|
||
|
import Data.List
|
||
|
import qualified Data.Vector.Sized as V
|
||
|
import Data.Map (Map)
|
||
|
import qualified Data.Map as M
|
||
|
import Data.Set (Set)
|
||
|
import qualified Data.Set as S
|
||
|
|
||
|
class Index i where
|
||
|
neighbours :: i -> [i]
|
||
|
addIndex :: i -> i -> i
|
||
|
|
||
|
counts :: Ord a => [a] -> Map a Int
|
||
|
counts = M.fromList . map (\xs -> (head xs, length xs)) . group . sort
|
||
|
|
||
|
neighbourCounts :: (Index i, Ord i) => Set i -> Map i Int
|
||
|
neighbourCounts = counts . concatMap neighbours . S.elems
|
||
|
|
||
|
update :: (Index i, Ord i) => (Int -> Bool) -> (Int -> Bool) -> Set i -> Set i
|
||
|
update create destroy old = M.keysSet $ M.filterWithKey shouldLive $ M.fromSet (flip (M.findWithDefault 0) nCounts) indices
|
||
|
where nCounts = neighbourCounts old
|
||
|
indices = S.union old $ M.keysSet nCounts
|
||
|
shouldLive ix n = if S.notMember ix old then create n else not $ destroy n
|