shiffman_pearson_textbook · wolframCA1DTextbook
Wolfram Elementary 1-D CA (Textbook)
The textbook Wolfram elementary cellular automaton. A 1-D row of dim cells with state in [0, K-1] evolves under a 3-neighborhood rule (left, self, right -> next). For K=2 this is the canonical Wolfram rule 0..255, with rule 30 (the chaotic poster-child), 90 (XOR), 110 (Turing-complete), and 184 (traffic) being the classic favourites. For K>2 it becomes Shiffman's cyclic CA: each cell increments its state if its right neighbour is (cell+1) mod K, otherwise stays. Each step() appends one row to a square dim x dim canvas so generations stack downward, unfurling the diagonal-of-time visualization. Started from a single live cell in the middle of an empty row (default) or a random row.
Original: https://natureofcode.com/cellular-automata/
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
For each cell i: idx = (row[i-1] * K^2 + row[i] * K + row[i+1]) mod K^3; next[i] = table[idx]. The 3^K-entry lookup table is encoded by treating the rule number as a base-K integer (K=2 -> 8-bit rule 0..255). Periodic boundary via np.roll. Each new generation is drawn onto the next canvas row with a 5-pixel cross stamp and an optional colour map (binary, viridis, magma, rainbow).
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 360 | 80–1200 | Canvas side / row length. |
rule | int | 30 | 0–255 | Wolfram rule (K=2 only). Classic picks: 30 (chaotic), 90 (XOR), 110 (Turing-complete), 184 (traffic). |
k | int | 2 | 2–8 | Cell-state alphabet size; K=2 is binary Wolfram, K>2 cyclic. |
seed_mode | str | single | — | How the first row is initialized. |
generations | int | 360 | 1–1200 | Total generations simulated; capped at dim. |
palette_mode | str | binary | — | Cell colour map (binary uses ink_color for live cells). |
bg_color | tuple | 245,240,230 | — | |
ink_color | tuple | 20,25,40 | — | |
seed | int | null | 0–999999 |
Reference
First 60 lines of reference.py. Full source:
library_external/shiffman_pearson_textbook/wolframCA1DTextbook/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
def _rule_bits(rule: int, k: int) -> np.ndarray:
"""Decode a 3^K-ary lookup rule to a K-state array of length k**3.
For K=2 this is the classic Wolfram 8-bit rule (0..255). For K>2 each
3-cell neighbourhood `(left, self, right)` with state in [0, K-1] maps
to a K-ary index `((left*K + self)*K + right)` whose value becomes the
rule's output. The rule number itself is written in base-K over k**3
digits.
"""
out = np.zeros(k ** 3, dtype=np.uint8)
v = int(rule)
for i in range(k ** 3):
out[i] = v % k
v //= k
if v == 0:
break
return out
class WolframCA1DTextbook:
"""Wolfram elementary cellular automaton — textbook rendering.
A 1-D row of ``dim`` cells each holding a value in ``[0, K-1]`` is
updated by a 3-neighborhood rule (left, self, right -> next). For K=2
this is the classic Wolfram rule 0..255 used everywhere in the
textbook (rule 30, 90, 110, 184 being the visual favourites).
For K>2 it becomes a cyclic cellular automaton: ``next = (cell + 1) mod K``
if the *right* neighbour has state ``(cell + 1) mod K`` and otherwise the
cell stays. This extension is also from Shiffman's Nature of Code Ch. 7.
Each step() appends one row to a square ``dim x dim`` history canvas, so
generations stack downward and the diagonal-of-time pattern emerges.
The default is K=2 with rule 30 (Wolfram's poster-child chaotic rule),
started from a single live cell in the middle of an empty row.
"""
family: ClassVar[str] = "shiffman_pearson_textbook"
sketch: ClassVar[str] = "wolframCA1DTextbook"
def __init__(
self,
dim: int = 360,
rule: int = 30,
k: int = 2,
seed_mode: str = "single",
rule_table: np.ndarray | None = None,
generations: int | None = None,
palette_mode: str = "binary",
bg_color: tuple[int, int, int] = (245, 240, 230),
ink_color: tuple[int, int, int] = (20, 25, 40),
seed: int | None = None,
) -> None:
self.dim = dim Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/shiffman_pearson_textbook/wolframCA1DTextbook/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from shiffman · pearson
Genetic Algorithm (Evolve Toward Target String)
shiffman_pearson_textbook · geneticAlgorithmString
A textbook genetic algorithm that evolves a population of binary strings toward a target ASCII string (default 'HELLO WORLD!').
Lindenmayer L-System (Textbook Formulation)
shiffman_pearson_textbook · lindenmayerTextbook
Lindenmayer L-system string rewriting with a 2-D turtle interpreter, the canonical textbook formulation used in both Shiffman's Nature of Code Ch.
Mandelbrot Set (Escape-Time Fractal)
shiffman_pearson_textbook · mandelbrotSet
The Mandelbrot set rendered by escape-time iteration of z = z^2 + c on a window of the complex plane.
Perlin Noise Flow Field
shiffman_pearson_textbook · perlinFlowField
A 2-D scalar field of Perlin gradient noise is sampled on a coarse grid; each cell is assigned a heading theta = 2*pi * n.
Random Walk / Drunkard's Walk
shiffman_pearson_textbook · randomWalkDrunkard
Many random walkers each start at the canvas center and take a stochastic 2-D step every tick.
Reynolds Boids (Separation / Alignment / Cohesion)
shiffman_pearson_textbook · boidsClassic
Reynolds' classic boids flocking model.