Created
August 23, 2021 08:18
-
-
Save roberto-arista/bb2c1f1aef00f6ec6035105bbfdb2f9a to your computer and use it in GitHub Desktop.
One dimensional cellular automata with three states
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
One dimensional cellular automata with three states | |
If you want to know more about CAs check "A New Kind of Science" by Stephen Wolfram | |
https://www.wolframscience.com/nks/ | |
""" | |
### Modules | |
import string | |
from random import choice | |
### Constants | |
POSSIBLE_SUMS = (6, 5, 4, 3, 2, 1, 0) | |
DIGITS = string.digits + string.ascii_letters | |
STATE_2_CHR = { | |
0: '⬜', | |
1: '🟦', | |
2: '⬛' | |
} | |
### Functions & Procedures | |
def makeRuleSet(rule): | |
results = f'{int2base(rule, 3):0>7}' | |
ruleSet = {k: int(v) for (k, v) in zip(POSSIBLE_SUMS, results)} | |
return ruleSet | |
def applyRules(lft, mid, rgt, ruleSet): | |
value = sum([lft, mid, rgt]) | |
return ruleSet[value] | |
def printCells(stripe): | |
stripeRepr = ''.join([STATE_2_CHR[ii] for ii in stripe]) | |
print(stripeRepr) | |
def int2base(x, base): | |
"""from https://stackoverflow.com/a/2267446""" | |
if x < 0: | |
sign = -1 | |
elif x == 0: | |
return DIGITS[0] | |
else: | |
sign = 1 | |
x *= sign | |
digits = [] | |
while x: | |
digits.append(DIGITS[int(x % base)]) | |
x = int(x / base) | |
if sign < 0: | |
digits.append('-') | |
digits.reverse() | |
return ''.join(digits) | |
### Variables | |
width = 45 | |
stripes = 45 | |
startWithRandomStripe = False | |
rule = 101 | |
assert 0 <= rule <= 2186 | |
### Instructions | |
if __name__ == '__main__': | |
if startWithRandomStripe: | |
stripe = [choice(STATE_2_CHR.keys()) for _ in range(width)] | |
else: | |
stripe = [0] * (width-1) | |
stripe.insert(width//2, 2) | |
ruleSet = makeRuleSet(rule) | |
printCells(stripe) | |
for eachStripe in range(stripes): | |
newStripe = [] | |
for index, mid in enumerate(stripe): | |
lft = stripe[(index-1) % len(stripe)] | |
rgt = stripe[(index+1) % len(stripe)] | |
newCell = applyRules(lft, mid, rgt, ruleSet) | |
newStripe.append(newCell) | |
stripe = list(newStripe) | |
printCells(stripe) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment