Skip to content

Instantly share code, notes, and snippets.

@AndrasKovacs
Last active April 10, 2020 07:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrasKovacs/f657cf65ef4fae8a345e993691bede82 to your computer and use it in GitHub Desktop.
Save AndrasKovacs/f657cf65ef4fae8a345e993691bede82 to your computer and use it in GitHub Desktop.
Cellular automata
{-# language Strict #-}
import qualified Data.Primitive.PrimArray as A
import GHC.Exts (IsList(..))
import Data.Bits
import Data.Word
type Rule = A.PrimArray Word8
mkRule :: Word8 -> Rule
mkRule w = fromList (map (fromIntegral . fromEnum . testBit w) [0..7])
step :: Rule -> A.PrimArray Word8 -> A.PrimArray Word8
step rule v = A.imapPrimArray update v where
len = A.sizeofPrimArray v
l = v `A.indexPrimArray` 0
r = v `A.indexPrimArray` (len - 1)
update :: Int -> Word8 -> Word8
update i center = rule `A.indexPrimArray` ruleIx where
left | i == 0 = r
| otherwise = v `A.indexPrimArray` (i - 1)
right | i == len - 1 = l
| otherwise = v `A.indexPrimArray` (i + 1)
ruleIx = fromIntegral (unsafeShiftL left 2 .|. unsafeShiftL center 1 .|. right)
runIterations :: Rule -> Int -> A.PrimArray Word8 -> A.PrimArray Word8
runIterations r n v = go n v where
go 0 v = v
go n v = go (n - 1) (step r v)
main :: IO ()
main = do
let v = fromList (1:replicate 1000 0)
print $ runIterations (mkRule 110) 1000000 v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment