Jump to content

Elementary cellular automaton/Random number generator: Difference between revisions

→‎{{header|Haskell}}: Added general random data generation
(→‎{{header|Haskell}}: Added Haskell solution)
(→‎{{header|Haskell}}: Added general random data generation)
Line 157:
<lang Haskell>import CellularAutomata (runCA, rule, fromList)
import Data.List (unfoldr)
import Control.Comonad (extract)
 
rnd = fromBits <$> unfoldr (pure . splitAt 8) bits
where size = 80
bits = extract <$> runCA (rule 30) (fromList (1:replicate size 0))
 
fromBits = foldl (\res x -> 2*res + x) 0</lang>
 
{{Out}}
<pre>λ> take 10 rnd
[220,197,147,174,117,97,149,171,240,241]</pre>
 
Using the rule 30 CA it is possible to determine the <code>RandomGen</code> instance which could be utilized by the <code>Random</code> class:
 
<lang Haskell>import System.Random
 
instance RandomGen (Cycle Int) where
next c = let x = c =>> step (rule 30) in (fromBits (view x), x)
split c = (c, fromList (reverse (view c)))</lang>
 
<pre>λ> let r30 = fromList [1,0,1,0,1,0,1,0,1,0,1,0,1] :: Cycle Int
 
λ> take 15 $ randoms r30
[7509,4949,2517,2229,2365,2067,6753,5662,5609,7576,2885,3017,2912,5081,2356]
 
λ> take 30 . randomRs ('A','J') $ r30
"DHJHHFJHBDDFCBHACHDEHDHFBAEJFE"</pre>
 
We can compare it with standard generator on a small integer range, using simple bin counter:
 
<pre>λ> let bins lst = [ (n, length (filter (==n) lst)) | n <- nub lst]
 
λ> bins . take 10000 . randomRs ('A','J') $ r30
[('D',1098),('H',1097),('J',1093),('F',850),('B',848),('C',1014),('A',1012),('E',1011),('G',1253),('I',724)]
 
λ> bins . take 10000 . randomRs ('A','J') <$> getStdGen
[('G',975),('B',1035),('F',970),('J',1034),('I',956),('H',984),('C',1009),('E',1023),('A',1009),('D',1005)]</pre>
 
=={{header|J}}==
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.