One-dimensional cellular automata: Difference between revisions

(→‎{{header|Haskell}}: Minor tidying)
(→‎Python :: Composition of pure functions: Tidied, updated primitives.)
Line 3,971:
 
Interpreting the rule shown in the task description as Wolfram rule 104, and generalising enough to allow for other rules of this kind:
<lang python>"""'''Cellular Automata"""'''
 
from itertools import (islice, repeat)
from functools import reduce
from random import randint
 
 
# ruleSample :: Int -> String
def ruleSample(intRule):
'''16 steps in the evolution of a specified Wolfram rule.'''
return 'Rule ' + str(intRule) + ':\n' + (
unlines(map(
showCells,
take(16)(
iterate(nextRowByRule(intRule))(
onePixelInLineOf(64) if bool(randint(0, 1)) else (
randomPixelsInLineOf(64)
)
)
)
))
)
 
 
Line 3,997 ⟶ 3,981:
def nextRowByRule(intRule):
'''A row of booleans derived by Wolfram rule n
from another boolean row of the same length.'''
'''
 
# step :: (Bool, Bool, Bool) -> Bool
def step(l, x, r):
Line 4,009 ⟶ 3,993:
xs, xs[1:], xs[2:]
)) + [False]
return lambda xs: go(xs)
 
 
# intFromBools :: [Bool] -> Int
def intFromBools(xs):
'''Integer derived by binary interpretation
of a list of booleans.'''
def go(b, pn):
power, n = pn
return (2 * power, n + power if b else n)
return foldr(go)([1, 0])(xs)[1]
 
 
# TEST --------------------------- TEST -------------------------
# main :: IO ()
def main():
Line 4,018 ⟶ 4,012:
 
print(
unlines(map(ruleSampleshowRuleSample, [104, 30, 110]))
)
 
 
# ----------------------- DISPLAY ------------------------
 
# ruleSampleshowRuleSample :: Int -> String
def ruleSampleshowRuleSample(intRule):
'''16 steps in the evolution of a specified Wolfram rule.'''
return 'Rule ' + str(intRule) + ':\n' + (
unlines(map(
showCells,
take(16)(
iterate(nextRowByRule(intRule))(
onePixelInLineOf(64) if bool(randint(0, 1)) else (
bool(randint(0, 1))
) else randomPixelsInLineOf(64)
)
)
))
)
 
Line 4,029 ⟶ 4,042:
return Just((x // 2, bool(x % 2))) if x else Nothing()
return unfoldl(go)(n)
 
 
# intFromBools :: [Bool] -> Int
def intFromBools(xs):
'''Integer derived by binary interpretation
of a list of booleans.'''
def go(b, pn):
power, n = pn
return (2 * power, n + power if b else n)
return foldr(go)([1, 0])(xs)[1]
 
 
Line 4,072 ⟶ 4,075:
 
 
# GENERIC ------------------------- GENERIC ------------------------
 
# Just :: a -> Maybe a
Line 4,089 ⟶ 4,092:
def foldr(f):
'''Right to left reduction of a list,
using athe binary operator.''' f, and
starting with an initial accumulator value.
def go(v, xs):
a = v'''
def forg(a, x in xs):
a =return f(x, a)
return lambda acc: lambda returnxs: areduce(
return lambda acc: lambda xs: go(accg, xs[::-1]), acc
)
 
 
# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
'''An infinite list of repeated applications of f to x.'''
applications of f to x.
'''
def go(x):
v = x
Line 4,106 ⟶ 4,112:
yield v
v = f(v)
return lambda x: go(x)
 
 
Line 4,113 ⟶ 4,119:
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.'''
'''
return lambda xs: (
def go(xs[0):n]
ifreturn isinstance(xs, list)
else list(islice(xs, xs[0:n))]
if isinstance(xs, (list, tuple))
)
else list(islice(xs, n))
))
return lambda xs: (go
 
 
# unfoldl(lambda x: Just(((x - 1), x)) if 0 != x else Nothing())(10)
# -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
def unfoldl(f):
Line 4,131 ⟶ 4,138:
and the residual b is used as the argument for the next
application of f.
When f returns Nothing, the completed list is returned.'''
'''
def go(v):
xrx, r = v, v
xs = []
while True:
mb = f(xr[0]x)
if mb.get('Nothing'):
return xs
else:
xrx, r = mb.get('Just')
xs.insert(0, xr[1]r)
return xs
return lambda x: go(x)
 
 
# unlines :: [String] -> String
def unlines(xs):
'''A single newline-delimited string derivedformed by the intercalation
fromof a list of strings with the newline character.'''
'''
return '\n'.join(xs)
 
9,655

edits