Rule 30 is one of the elementary cellular automaton rules introduced by Stephen Wolfram in 1983. It specifies the next color in a cell, depending on its color, and its immediate neighbors (Source).
The formula is [left_cell XOR (center_cell OR right_cell)]
. It is called Rule 30 because in binary 00011110 = 30
(Source).
This version is written in Python.
Python's argparse
has a nice built in help
command:
C:\...\rule30> python cli.py -h
usage: cli.py [-h] [--np] [--naive] [--steps STEPS]
Run Rule 30 automaton.
options:
-h, --help show this help message and exit
--np Use NumPy implementation
--naive Use naive implementation
--steps STEPS Specify the number of steps
To run Rule 30 for 5 steps, we simply use the --steps
flag and pass the parameter 5
:
C:\...\rule30> python cli.py --np --steps 5
Running Rule 30 cellular automaton for 5 steps (using a Python implementation with NumPy)
█
███
██ █
██ ████
██ █ █
█ ████ ██
Here we see Rule 30 for 10 steps:
C:\...\rule30> python cli.py --np --steps 10
Running Rule 30 cellular automaton for 10 steps (using a Python implementation with NumPy)
█
███
██ █
██ ████
██ █ █
██ ████ ███
██ █ █ █
██ ████ ██████
██ █ ███ █
██ ████ ██ █ ███
█ █ █ ████ ██
20 steps:
C:\...\rule30> python cli.py --np --steps 20
Running Rule 30 cellular automaton for 20 steps (using a Python implementation with NumPy)
█
███
██ █
██ ████
██ █ █
██ ████ ███
██ █ █ █
██ ████ ██████
██ █ ███ █
██ ████ ██ █ ███
██ █ █ ████ ██ █
██ ████ ██ █ █ ████
██ █ ███ ██ ██ █ █
██ ████ ██ ███ ███ ██ ███
██ █ █ ███ █ ███ █ █
██ ████ ██ █ █ █████ ███████
██ █ ███ ████ █ ███ █
██ ████ ██ ███ ██ ██ █ ███
██ █ █ ███ █ ██ ███ ████ ██ █
██ ████ ██ █ ██████ █ █ ███ ████
█ █ ███ ████ ████ ███ ██ █
And finally, 50 steps:
C:\...\rule30> python cli.py --np --steps 50
Running Rule 30 cellular automaton for 50 steps (using a Python implementation with NumPy)
█
███
██ █
██ ████
██ █ █
██ ████ ███
██ █ █ █
██ ████ ██████
██ █ ███ █
██ ████ ██ █ ███
██ █ █ ████ ██ █
██ ████ ██ █ █ ████
██ █ ███ ██ ██ █ █
██ ████ ██ ███ ███ ██ ███
██ █ █ ███ █ ███ █ █
██ ████ ██ █ █ █████ ███████
██ █ ███ ████ █ ███ █
██ ████ ██ ███ ██ ██ █ ███
██ █ █ ███ █ ██ ███ ████ ██ █
██ ████ ██ █ ██████ █ █ ███ ████
██ █ ███ ████ ████ ███ ██ █ █
██ ████ ██ ███ █ ██ █ █ █ ███ ███
██ █ █ ███ █ ███ ██ █ ███ ██ █ █ █ █
██ ████ ██ █ ███ █ █ ████ █ █ ██ ██████
██ █ ███ ████ ██ █████ █ █████ █ █ █
██ ████ ██ ███ █ ██ █ █ ██ █ █████ ███
██ █ █ ███ █ ██ █ ████ ██ █ ██ ██ █ ██ █
██ ████ ██ █ ███ █ █ █ ███ ████ █ ██ █ ██ █ ████
██ █ ███ ████ ████ ██ ██ ███ █ █ ████ █ █ █
██ ████ ██ ███ █ ██ █ █ ███ █ ██ ████ ███ ██ ███
██ █ █ ███ █ ██ █ █ █████ █ ██████ █ █ ██ █ █ █
██ ████ ██ █ ███ █ █ ████ ████ ████ ██ █ █ █████████
██ █ ███ ████ ████ █ █ ██ █ ██ █ █ █ █ █
██ ████ ██ ███ █ ██ ██ ███ ██ █ ███ ██ █ █████ █ ██ ███
██ █ █ ███ █ ██ █ █ ██ █ █ █ █ █ ████ █ █ █ ██ █
██ ████ ██ █ ███ █ █ ████ ████ █████ ██ █████ █ ██ █ ██ ██ ████
██ █ ███ ████ ████ █ █ █ █ █ █ ███ ██ █ █ ███ █ █
██ ████ ██ ███ █ ██ ██ ███ ███ ██████ ██ █ █ ███ █ █ ████ ███
██ █ █ ███ █ ██ █ █ ██ ███ ███ █ ██ ███ ██ ██ █ █ ████ █ █
██ ████ ██ █ ███ █ █ ████ █ ███ ███ █ █ ██ ███ █ ██ ██ █ █ ██████
██ █ ███ ████ ████ █ ██████ ███ █ ██ ██ ███ ██████ █ ██ █████ █
██ ████ ██ ███ █ ██ ██ ██ ███ █ ██ █ █ █ ███ ██████ █ █ ███
██ █ █ ███ █ ██ █ █ ██ █ █ ██ ███ █ ██████████ █ ██ ████ ███ ██ █
██ ████ ██ █ ███ █ █ ████ ███ ██ ██ ███ ████ ████ ██ █ ██ ███ █ ████
██ █ ███ ████ ████ █ █ █ █ █ █ ██ █ ██ █ ██ ██ █ ██ █ ██ █ █
██ ████ ██ ███ █ ██ ██ ███ ███████████ █ █ ███ ██ █ █████ █ █ █ ███ █ ██ ███
██ █ █ ███ █ ██ █ █ ██ ███ █ █ █ █ █ ██ ████ ██████ █ █ ████ █ █
██ ████ ██ █ ███ █ █ ████ █ █ ███ ██ █ █████ ██ ███ █ ██ █ ██ ██ ███████
██ █ ███ ████ ████ █ ██████ █ █ ██ █ █ █ █ █ █████ █ ██ █ █ █ ██ █
██ ████ ██ ███ █ ██ ██ ██ █████ ██ ███ ██ ████████ █ ██ ██ ████ █ █ █ ███
█ █ █ ███ █ ██ █ █ ██ █ █ ██ █ ██ █ █ █ ██ ██ ██ ███ ███ █ █ ██ ██
Beautiful!
The above examples were all generated based on my implementation using numpy. I also implemented Rule 30 more naively (un-vectorized) using native Python data structures and libraries, which can be called with the --naive
flag:
C:\...\rule30> python cli.py --naive --steps 10
Running Rule 30 cellular automaton for 10 steps (using a naive Python implementation)
█
███
██ █
██ ████
██ █ █
██ ████ ███
██ █ █ █
██ ████ ██████
██ █ ███ █
██ ████ ██ █ ███
██ █ █ ████ ██
I learned about Rule 30 for the first time a few weeks when I was listening to Lex Fridman interview Stephen Wolfram on Lex's podcast (I highly recommend a listen!).
Feedback, bug reports, issues, and pull requests welcome!