Files
Python/cellular_automata/elementary_cellular_automaton.py
Sarthak Joshiandpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 17cbde1f7d add Elementary Cellular Automaton (Rule 30) implementation (Hacktoberfest 2025) (#13827)
* Create elementary_cellular_automaton.py

Elementary Cellular Automaton (Rule 30) implementation

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update elementary_cellular_automaton.py

* Update elementary_cellular_automaton.py

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2026-09-05 10:25:26 +02:00

75 lines
2.1 KiB
Python

"""
Elementary Cellular Automaton - Rule 30
---------------------------------------
A one-dimensional cellular automaton introduced by Stephen Wolfram.
Each cell's next state depends on its current state and its two immediate neighbors.
Reference:
https://en.wikipedia.org/wiki/Rule_30
"""
def rule_30_step(current: list[int]) -> list[int]:
"""
Compute the next generation of a one-dimensional cellular automaton
following Wolfram's Rule 30.
Each cell's next state is determined by its left, center, and right neighbors.
Args:
current (list[int]): The current generation as a list of 0s (dead)
and 1s (alive).
Returns:
list[int]: The next generation as a list of 0s and 1s.
Example:
>>> rule_30_step([0, 0, 1, 0, 0])
[0, 1, 1, 1, 0]
"""
next_gen = []
for i in range(len(current)):
left = current[i - 1] if i > 0 else 0
center = current[i]
right = current[i + 1] if i < len(current) - 1 else 0
# Combine neighbors into a 3-bit pattern
pattern = (left << 2) | (center << 1) | right
# Rule 30 binary: 00011110 (bitwise representation of 30)
next_gen.append((30 >> pattern) & 1)
return next_gen
def generate_rule_30(size: int = 31, generations: int = 15) -> list[list[int]]:
"""
Generate multiple generations of Rule 30 automaton.
Args:
size (int): Number of cells in one generation. Default is 31.
generations (int): Number of generations to evolve. Default is 15.
Returns:
list[list[int]]: A list of generations (each a list of 0s and 1s).
Example:
>>> len(generate_rule_30(15, 5))
5
"""
grid = [[0] * size for _ in range(generations)]
grid[0][size // 2] = 1 # Start with a single live cell in the middle
for i in range(1, generations):
grid[i] = rule_30_step(grid[i - 1])
return grid
if __name__ == "__main__":
# Run an example simulation
generations = generate_rule_30(31, 15)
for row in generations:
print("".join("█" if cell else " " for cell in row))