First Post: Cellular Automata Simulator
Submitted by Revision17 on Sun, 04/02/2006 - 7:16pm.
::
Alright, I'm new to haskell, and I just wrote a cellular automata simlator that a few people have expressed interest in seeing, so here it is:
module Main where
import Data.Bits
import Text.Printf (printf)
newtype State = State ([Bool],Int)
stateLineToString (x:xs) | x == True = 'X':(stateLineToString xs)
| otherwise = ' ':(stateLineToString xs)
stateLineToString [] = "|"
instance Show (State) where
show (State (x,y)) = printf "%04.0d:%s|" y (stateLineToString x)
{-
hood = 3 cell neighborhood; this determines which bit of the ruleNumber we look at for the result; it's three least significant bits determine which neighborhood it is
-}
applyRule :: Int -> (Bool,Bool,Bool) -> Bool
applyRule ruleNum hood = testBit ruleNum (tripleToInt hood)
tripleToInt :: (Bool,Bool,Bool) -> Int
tripleToInt (x,y,z) = (x `trueNum` 4) + (y `trueNum` 2) + (z `trueNum` 1)
where
trueNum x y | x == True = y
| otherwise = 0
applyRuleToState :: ((Bool,Bool,Bool) -> Bool) -> State -> State -- [Bool] -> [Bool]
applyRuleToState f (State (x,y)) = State (False:(applyRuleToList f x),(y+1))
applyRuleToList :: ((Bool,Bool,Bool) -> Bool) -> [Bool] -> [Bool]
applyRuleToList rule (a:b:c:rest) = (rule (a,b,c)):(applyRuleToList rule (b:c:rest))
applyRuleToList _ [x,y] = [x]
testState = State ((take 100 (repeat False)) ++ [True] ++ (take 100 (repeat False)),0)
test = applyRuleToState rule30 testState
rule30 = applyRule 30
rule30All = iterate (applyRuleToState rule30) testState
rule90 = applyRule 90
rule90All = iterate (applyRuleToState rule90) testState
rulesToString :: [State] -> String
rulesToString (x:xs) = ((show x) ++ ['\n'])++(rulesToString xs)
rulesToSTring [] = ['\n']
main :: IO ()
main = putStrLn (rulesToString (take 100 rule90All))
As I'm still new there are some sloppy things with it, but it'll output a rule 90 cellular automata. With slight modification, it'll output any that use 3 cell neighborhoods.
- Revision17's blog
- Login to post comments