Last active
May 14, 2023 23:03
-
-
Save GeoffChurch/708a02843313069b95df7809e1eec673 to your computer and use it in GitHub Desktop.
Wolfram's "rule 30" cellular automaton. Read it, download it, and then execute `python rule30_animation.py` from your terminal in the same directory.
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
from os import get_terminal_size | |
from time import sleep | |
terminal_size = get_terminal_size() | |
num_cells = terminal_size.columns # We'll have as many cells as can fit in the terminal's width | |
sleep_time = 4.0 / terminal_size.lines # Animation speed will be proportional to the terminal's height | |
# Lookup table for Wolfram's "rule 30" cellular automaton | |
RULE_30 = { | |
(0,0,0) : 0, | |
(0,0,1) : 1, | |
(0,1,0) : 1, | |
(0,1,1) : 1, | |
(1,0,0) : 1, | |
(1,0,1) : 0, | |
(1,1,0) : 0, | |
(1,1,1) : 0, | |
} | |
# Initialize state with a single 1 in the middle: | |
state = [0] * num_cells # Create a list of length "num_cells" containing all 0's. | |
state[num_cells // 2] = 1 # Set the middle cell to 1. If num_cells is even this will be just to the left of the middle. | |
while True: # "while True" means "repeat the following block forever". "while 1 == 1" would have the same effect. | |
# Print current state, using spaces for 0's and rectangles for 1's. "''.join(...)" turns "['█', ' ', '█']" into "█ █". | |
print(''.join([' ' if cell == 0 else '█' for cell in state])) | |
# Update state by looking at each cell (at index i) and its left and right neighbors (at i-1 and i+1). | |
# The first cell's (state[0]) left neighbor should be the last cell. Python handles this for us automatically by taking state[-1] to mean the last cell. | |
# Similarly, the last cell's (state[num_cells-1]) right neighbor should be the first cell. | |
# Python doesn't handle this for us, so we use "(i+1) % num_cells" (remainder after division) to wrap around to the beginning as needed. | |
state = [RULE_30[state[i-1], state[i], state[(i+1) % num_cells]] for i in range(num_cells)] | |
# Wait a moment before the next iteration | |
sleep(sleep_time) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment