Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Cellular automata in Python
#!/usr/bin/env python3
"""
Cellular automata in Python
"""
import sys
Z = '.'
O = '#'
def init(width=79):
""" The initial string
"""
m = width // 2
s = ""
for i in range(m):
s += Z
s += O
for i in range(m):
s += Z
return s
def from_bin(bb):
"""
>>> from_bin([1,0,0])
4
"""
r = 0
for i, b in enumerate(bb):
j = len(bb) - i - 1
r += b * 2**j
return r
def to_bin(i, min_len=8):
"""
>>> to_bin(4, min_len=5)
[0, 0, 1, 0, 0]
>>> to_bin(5, min_len=5)
[0, 0, 1, 0, 1]
"""
bs = []
while i > 0:
r = i % 2
bs = [r] + bs # Prepend r
i = i // 2
if len(bs) < min_len:
bs = [0] * (min_len - len(bs)) + bs
return bs
def b2s(b):
r = ""
for x in b:
r += (O if x == 1 else Z)
return r
def s2b(s):
return [1 if x == O else 0 for x in s]
def interpret_rule(rule, state):
"""
>>> interpret_rule(16, [Z,O,O])
'.'
>>> interpret_rule(16, [O,Z,Z])
'#'
>>> interpret_rule(16, [Z,Z,O])
'.'
"""
i = from_bin(s2b(state))
bin_rule = b2s(to_bin(rule, min_len=8))
return bin_rule[::-1][i] # Reverse the rule bits
def evolve(rule, state, w=3):
"""
w is window width (3 for CA)
"""
m = len(state)
s = ""
rr = [i for i in range(m)]
# Shift starting index left by one
rr = [rr[-1]] + rr[:-1]
for l in rr:
if l > m - w:
r = w - m + l
cell = state[l:l+w] + state[:r]
else:
cell = state[l:l+w]
s += interpret_rule(rule, cell)
return s
def main(rule, iters=39):
s = init()
print(s)
for i in range(iters):
s = evolve(rule, s)
print(s)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: %s RULENO" % (sys.argv[0]))
exit()
rule = int(sys.argv[1])
main(rule)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment