Skip to content

Commit 0ef9dd3

Browse files
8Dion8cclauss
andauthored
Create one_dimensional.py (TheAlgorithms#1905)
* Create one_dimensional.py * Update cellular_automata/one_dimensional.py Co-Authored-By: Christian Clauss <cclauss@me.com> * Update cellular_automata/one_dimensional.py Co-Authored-By: Christian Clauss <cclauss@me.com> * Update one_dimensional.py Moved import to the top so that the type Image gets recognized * Update one_dimensional.py * Update cellular_automata/one_dimensional.py * Update cellular_automata/one_dimensional.py * Update one_dimensional.py * Update one_dimensional.py * Update one_dimensional.py Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent 5933cd4 commit 0ef9dd3

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

cellular_automata/one_dimensional.py

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"""
2+
Return an image of 16 generations of one-dimensional cellular automata based on a given
3+
ruleset number
4+
https://mathworld.wolfram.com/ElementaryCellularAutomaton.html
5+
"""
6+
7+
from typing import List
8+
9+
from PIL import Image
10+
11+
# Define the first generation of cells
12+
# fmt: off
13+
CELLS = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
14+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
15+
# fmt: on
16+
17+
18+
def format_ruleset(ruleset: int) -> List[int]:
19+
"""
20+
>>> format_ruleset(11100)
21+
[0, 0, 0, 1, 1, 1, 0, 0]
22+
>>> format_ruleset(0)
23+
[0, 0, 0, 0, 0, 0, 0, 0]
24+
>>> format_ruleset(11111111)
25+
[1, 1, 1, 1, 1, 1, 1, 1]
26+
"""
27+
return [int(c) for c in f"{ruleset:08}"[:8]]
28+
29+
30+
def new_generation(cells: List[List[int]], rule: List[int], time: int) -> List[int]:
31+
population = len(cells[0]) # 31
32+
next_generation = []
33+
for i in range(population):
34+
# Get the neighbors of each cell
35+
left_neighbor = 0 if i == 0 else cells[time][i - 1] # special: leftmost cell
36+
right_neighbor = 0 if i == population - 1 else cells[time][i + 1] # rightmost
37+
# Define a new cell and add it to the new generation
38+
situation = 7 - int(f"{left_neighbor}{cells[time][i]}{right_neighbor}", 2)
39+
next_generation.append(rule[situation])
40+
return next_generation
41+
42+
43+
def generate_image(cells: List[List[int]]) -> Image.Image:
44+
"""
45+
Convert the cells into a greyscale PIL.Image.Image and return it to the caller.
46+
>>> from random import random
47+
>>> cells = [[random() for w in range(31)] for h in range(16)]
48+
>>> img = generate_image(cells)
49+
>>> isinstance(img, Image.Image)
50+
True
51+
>>> img.width, img.height
52+
(31, 16)
53+
"""
54+
# Create the output image
55+
img = Image.new("RGB", (len(cells[0]), len(cells)))
56+
pixels = img.load()
57+
# Generates image
58+
for w in range(img.width):
59+
for h in range(img.height):
60+
color = 255 - int(255 * cells[h][w])
61+
pixels[w, h] = (color, color, color)
62+
return img
63+
64+
65+
if __name__ == "__main__":
66+
rule_num = bin(int(input("Rule:\n").strip()))[2:]
67+
rule = format_ruleset(int(rule_num))
68+
for time in range(16):
69+
CELLS.append(new_generation(CELLS, rule, time))
70+
img = generate_image(CELLS)
71+
# Uncomment to save the image
72+
# img.save(f"rule_{rule_num}.png")
73+
img.show()

0 commit comments

Comments
 (0)