mirror of
https://github.com/TheAlgorithms/Python.git
synced 2026-09-29 05:53:07 +08:00
* 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>
75 lines
2.1 KiB
Python
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))
|