Created
February 20, 2020 22:17
-
-
Save timfi/4141609c67735048d233377cb01bb6e9 to your computer and use it in GitHub Desktop.
Elementary Cellular Automata
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
"""elementary.py | |
Summary | |
------- | |
This module implements 1D cellular automata, i.e. elementary cellular automata [1], | |
using rules formatted in Wolfram code [2]. | |
Parameters | |
---------- | |
rule : int, positive | |
The rule to simulate. This should be a 8-bit integer, you can make it bigger | |
but this function will only use the 8 least significant bits. | |
width : int, positive | |
The total width of the state you want to simulate. | |
iterations : int, positive | |
The number of iterations to simulate. | |
Usage | |
----- | |
Running this module from the commandline will yield a PBM-formatted image of the | |
simulation result. You can redirect stdout to a file or pipe the image into other | |
tools like magick or convert to further process the image. | |
References | |
---------- | |
.. [1] Weisstein, Eric W. "Elementary Cellular Automaton." | |
From MathWorld--A Wolfram Web Resource. | |
http://mathworld.wolfram.com/ElementaryCellularAutomaton.html | |
.. [2] Wolfram, Stephen (July 1983). "Statistical Mechanics of Cellular Automata". | |
Reviews of Modern Physics. 55: 601–644. Bibcode:1983RvMP...55..601W. | |
""" | |
from typing import Iterator | |
import random | |
__all__ = ("simulate",) | |
def simulate(rule: int, width: int, inital_state: int = -1, iterations: int = -1) -> Iterator[int]: | |
"""Simulate 1D cellular automata. | |
Parameters | |
---------- | |
rule : int | |
The rule to simulate. This should be a 8-bit integer, you can make it bigger | |
but this function will only use the 8 least significant bits. | |
width : int | |
The total width of the state you want to simulate. | |
inital_state : int | |
The state to start the simulation with. (the default is -1, which forces the | |
random generation of an initial state) | |
iterations : int | |
The number of iterations to simulate. (the default is -1, which causes the | |
simulation to run indefinitely) | |
Yields | |
------ | |
state : int | |
The current state of the simulation. | |
Examples | |
-------- | |
>>> for state in simulate(30, 8, iterations=8): | |
... print(f"{state:0>8b}") | |
01011110 | |
11010001 | |
00011011 | |
10110010 | |
10101110 | |
10101000 | |
10101101 | |
00101001 | |
""" | |
pattern = { | |
i: rule >> i & 1 | |
for i in range(8) | |
} | |
if inital_state < 0: | |
inital_state = random.randrange(2 ** width) | |
i, state = 0, inital_state | |
while iterations < 0 or i < iterations: | |
i += 1 | |
state = sum( | |
pattern[( | |
(state >> (i - 1) % width & 1) << 0 | | |
(state >> (i + 0) % width & 1) << 1 | | |
(state >> (i + 1) % width & 1) << 2 | |
)] << i | |
for i in range(width) | |
) | |
yield state | |
if __name__ == "__main__": | |
import sys | |
try: | |
s_rule, s_width, s_iterations = sys.argv[1:] | |
rule = int(s_rule) | |
width = int(s_width) | |
iterations = int(s_iterations) | |
except: | |
print("Usage: python elementary.py RULE WIDTH ITERATIONS") | |
sys.exit(1) | |
if rule < 0 or width < 0 or iterations < 0: | |
sys.stderr.write("All parameters should be positive integers.\n") | |
sys.exit(1) | |
state_format = f"{{state:0>{width}b}}" | |
print(f"P1\n{width} {iterations}") | |
for state in simulate(rule, width, iterations=iterations): | |
print(state_format.format(state=state)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment