From f501079b1696b9b5d3c448e22bc58b1a0071622b Mon Sep 17 00:00:00 2001 From: 8Dion8 <62215043+8Dion8@users.noreply.github.com> Date: Fri, 24 Apr 2020 08:41:13 +0300 Subject: [PATCH 01/10] Create one_dimensional.py --- cellular_automata/one_dimensional.py | 93 ++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 cellular_automata/one_dimensional.py diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py new file mode 100644 index 000000000000..942e53d46470 --- /dev/null +++ b/cellular_automata/one_dimensional.py @@ -0,0 +1,93 @@ +''' +Returns an image of 16 generations of +one-dimensional cellular automata +based on a given ruleset number +https://mathworld.wolfram.com/ElementaryCellularAutomaton.html +''' +# Formats inputted ruleset +def format_ruleset(RULE_NUM): + ''' + >>> format_ruleset(11100) + [0,0,0,1,1,1,0,0] + >>> format_ruleset(0) + [0,0,0,0,0,0,0,0] + >>> format_ruleset(11111111) + [1,1,1,1,1,1,1,1] + ''' + RULE = [int(a) for a in RULE_NUM] + while True: + if len(RULE) == 8: + break + else: + RULE.insert(0, 0) + #returns formatted ruleset + return(RULE) + +# Defines the first generation of cells + +CELLS = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,]] + +# Mainloop + +def new_generation(CELLS,RULE,time): + new_row = [] + + for i in range(31): + + # Gets neighbors of a cell + + # If leftmost cell is in consideration + + if i == 0: + left_neighbor = 0 + right_neighbor = CELLS[time][i + 1] + elif i == 30: + + # If rightmost cell is in consideration + + left_neighbor = CELLS[time][i - 1] + right_neighbor = 0 + else: + + # All other cells + + left_neighbor = CELLS[time][i - 1] + right_neighbor = CELLS[time][i + 1] + + # Defines new cell in and adds it to the new generation + + SITUATION = 7 - int(str(left_neighbor) + str(CELLS[time][i]) + + str(right_neighbor), 2) + new_row.append(RULE[SITUATION]) + #returns new generation + return new_row + +def generate_image(CELLS): + # Creates the outputting image + + RESULT = Image.new('RGB', (31, 16)) + PIXELS = RESULT.load() + + # Generates image + for w in range(31): + for h in range(16): + color = 255 - 255 * CELLS[h][w] + PIXELS[w, h] = (color, color, color) + + # Uncomment for saving the image + # RESULT.save('RULE '+str(RULE_NUM)) + + # Shows the image + RESULT.show() + +if __name__ == '__main__': + from PIL import Image + + RULE_NUM = bin(int(input('Rule\n')))[2:] + RULE = format_ruleset(RULE_NUM) + + for time in range(16): + CELLS.append(new_generation(CELLS,RULE,time)) + + generate_image(CELLS) From af2e65774b44deb99949e86b77f44c9e10bf042b Mon Sep 17 00:00:00 2001 From: 8Dion8 <62215043+8Dion8@users.noreply.github.com> Date: Fri, 24 Apr 2020 10:36:18 +0300 Subject: [PATCH 02/10] Update cellular_automata/one_dimensional.py Co-Authored-By: Christian Clauss --- cellular_automata/one_dimensional.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index 942e53d46470..03eb5fece22e 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -63,7 +63,10 @@ def new_generation(CELLS,RULE,time): #returns new generation return new_row -def generate_image(CELLS): +def generate_image(CELLS: list) -> Image: + """ + Convert the cells into a PIL.Image and return it to the caller. + """ # Creates the outputting image RESULT = Image.new('RGB', (31, 16)) From 3fb7dc1365c0d2b7b3b73dc8456cf2b67d476e9d Mon Sep 17 00:00:00 2001 From: 8Dion8 <62215043+8Dion8@users.noreply.github.com> Date: Fri, 24 Apr 2020 10:41:48 +0300 Subject: [PATCH 03/10] Update cellular_automata/one_dimensional.py Co-Authored-By: Christian Clauss --- cellular_automata/one_dimensional.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index 03eb5fece22e..300055d4189e 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -4,8 +4,7 @@ based on a given ruleset number https://mathworld.wolfram.com/ElementaryCellularAutomaton.html ''' -# Formats inputted ruleset -def format_ruleset(RULE_NUM): +def format_ruleset(ruleset: int) -> list: ''' >>> format_ruleset(11100) [0,0,0,1,1,1,0,0] @@ -14,14 +13,7 @@ def format_ruleset(RULE_NUM): >>> format_ruleset(11111111) [1,1,1,1,1,1,1,1] ''' - RULE = [int(a) for a in RULE_NUM] - while True: - if len(RULE) == 8: - break - else: - RULE.insert(0, 0) - #returns formatted ruleset - return(RULE) + return [int(c) for c in f"{ruleset:08}"[:8]] # Defines the first generation of cells From 5eaaf993ec2bfeae94f31116793ed0baef08fd79 Mon Sep 17 00:00:00 2001 From: 8Dion8 <62215043+8Dion8@users.noreply.github.com> Date: Fri, 24 Apr 2020 11:06:23 +0300 Subject: [PATCH 04/10] Update one_dimensional.py Moved import to the top so that the type Image gets recognized --- cellular_automata/one_dimensional.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index 300055d4189e..eb3d65652f3a 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -1,3 +1,4 @@ +from PIL import Image ''' Returns an image of 16 generations of one-dimensional cellular automata @@ -77,7 +78,6 @@ def generate_image(CELLS: list) -> Image: RESULT.show() if __name__ == '__main__': - from PIL import Image RULE_NUM = bin(int(input('Rule\n')))[2:] RULE = format_ruleset(RULE_NUM) From fc270dd758707373a69e8baaca22ae2415f4de28 Mon Sep 17 00:00:00 2001 From: 8Dion8 <62215043+8Dion8@users.noreply.github.com> Date: Fri, 24 Apr 2020 11:15:26 +0300 Subject: [PATCH 05/10] Update one_dimensional.py --- cellular_automata/one_dimensional.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index eb3d65652f3a..3f0f87816b6b 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -8,11 +8,11 @@ def format_ruleset(ruleset: int) -> list: ''' >>> format_ruleset(11100) - [0,0,0,1,1,1,0,0] + [0, 0, 0, 1, 1, 1, 0, 0] >>> format_ruleset(0) - [0,0,0,0,0,0,0,0] + [0, 0, 0, 0, 0, 0, 0, 0] >>> format_ruleset(11111111) - [1,1,1,1,1,1,1,1] + [1, 1, 1, 1, 1, 1, 1, 1] ''' return [int(c) for c in f"{ruleset:08}"[:8]] From 5903e24d6e092044c70746ad95cc3bb9bf90b8f5 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 25 Apr 2020 19:52:45 +0200 Subject: [PATCH 06/10] Update cellular_automata/one_dimensional.py --- cellular_automata/one_dimensional.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index 3f0f87816b6b..4a9e5ea03634 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -58,7 +58,14 @@ def new_generation(CELLS,RULE,time): def generate_image(CELLS: list) -> Image: """ - Convert the cells into a PIL.Image and return it to the caller. + Convert the cells into a PIL.Image.Image and return it to the caller. + >>> from random import randint + >>> cells = [[randint(0, 1) for w in range(31)] for h in range(16)] + >>> img = generate_image(cells) + >>> isinstance(img, PIL.Image.Image) + True + >>> img.size + (31, 16) """ # Creates the outputting image From 7d8fc25c97d3858051f74244bf1ee7086baadf56 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sat, 25 Apr 2020 19:53:11 +0200 Subject: [PATCH 07/10] Update cellular_automata/one_dimensional.py --- cellular_automata/one_dimensional.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index 4a9e5ea03634..f58837c137c5 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -77,7 +77,7 @@ def generate_image(CELLS: list) -> Image: for h in range(16): color = 255 - 255 * CELLS[h][w] PIXELS[w, h] = (color, color, color) - + return RESULT # Uncomment for saving the image # RESULT.save('RULE '+str(RULE_NUM)) From ccc0b48e06b89e484fb51fbea8de7ea7dcc4ccb7 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 26 Apr 2020 02:39:20 +0200 Subject: [PATCH 08/10] Update one_dimensional.py --- cellular_automata/one_dimensional.py | 126 ++++++++++++--------------- 1 file changed, 55 insertions(+), 71 deletions(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index f58837c137c5..ac34a97b153e 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -1,95 +1,79 @@ -from PIL import Image -''' -Returns an image of 16 generations of -one-dimensional cellular automata -based on a given ruleset number +""" +Return an image of 16 generations of one-dimensional cellular automata based on a given +ruleset number https://mathworld.wolfram.com/ElementaryCellularAutomaton.html -''' -def format_ruleset(ruleset: int) -> list: - ''' +""" + +from typing import List + +from PIL import Image + +# Define the first generation of cells +# fmt: off +CELLS = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] +# fmt: on + + +def format_ruleset(ruleset: int) -> List[int]: + """ >>> format_ruleset(11100) [0, 0, 0, 1, 1, 1, 0, 0] >>> format_ruleset(0) [0, 0, 0, 0, 0, 0, 0, 0] >>> format_ruleset(11111111) [1, 1, 1, 1, 1, 1, 1, 1] - ''' + """ return [int(c) for c in f"{ruleset:08}"[:8]] -# Defines the first generation of cells - -CELLS = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,]] - -# Mainloop - -def new_generation(CELLS,RULE,time): - new_row = [] +def new_generation(cells: List[List[int]], rule: List[int], time: int) -> List[int]: + next_generation = [] for i in range(31): - - # Gets neighbors of a cell - - # If leftmost cell is in consideration - - if i == 0: + # Get the neighbors of each cell + if i == 0: # leftmost cell left_neighbor = 0 - right_neighbor = CELLS[time][i + 1] - elif i == 30: - - # If rightmost cell is in consideration - - left_neighbor = CELLS[time][i - 1] + right_neighbor = cells[time][i + 1] + elif i == 30: # rightmost cell + left_neighbor = cells[time][i - 1] right_neighbor = 0 - else: - - # All other cells + else: # All other cells + left_neighbor = cells[time][i - 1] + right_neighbor = cells[time][i + 1] + # Define a new cell and add it to the new generation + situation = 7 - int(f"{left_neighbor}{cells[time][i]}{right_neighbor}", 2) + next_generation.append(rule[situation]) + return next_generation - left_neighbor = CELLS[time][i - 1] - right_neighbor = CELLS[time][i + 1] - # Defines new cell in and adds it to the new generation - - SITUATION = 7 - int(str(left_neighbor) + str(CELLS[time][i]) - + str(right_neighbor), 2) - new_row.append(RULE[SITUATION]) - #returns new generation - return new_row - -def generate_image(CELLS: list) -> Image: +def generate_image(cells: List[List[int]]) -> Image.Image: """ - Convert the cells into a PIL.Image.Image and return it to the caller. - >>> from random import randint - >>> cells = [[randint(0, 1) for w in range(31)] for h in range(16)] + Convert the cells into a greyscale PIL.Image.Image and return it to the caller. + >>> from random import random + >>> cells = [[random() for w in range(31)] for h in range(16)] >>> img = generate_image(cells) - >>> isinstance(img, PIL.Image.Image) + >>> isinstance(img, Image.Image) True - >>> img.size + >>> img.width, img.height (31, 16) """ - # Creates the outputting image - - RESULT = Image.new('RGB', (31, 16)) - PIXELS = RESULT.load() - + # Create the output image + img = Image.new("RGB", (len(cells[0]), len(cells))) + pixels = img.load() # Generates image - for w in range(31): - for h in range(16): - color = 255 - 255 * CELLS[h][w] - PIXELS[w, h] = (color, color, color) - return RESULT - # Uncomment for saving the image - # RESULT.save('RULE '+str(RULE_NUM)) - - # Shows the image - RESULT.show() + for w in range(img.width): + for h in range(img.height): + color = 255 - int(255 * cells[h][w]) + pixels[w, h] = (color, color, color) + return img -if __name__ == '__main__': - - RULE_NUM = bin(int(input('Rule\n')))[2:] - RULE = format_ruleset(RULE_NUM) +if __name__ == "__main__": + rule_num = bin(int(input("Rule:\n").strip()))[2:] + rule = format_ruleset(int(rule_num)) for time in range(16): - CELLS.append(new_generation(CELLS,RULE,time)) - - generate_image(CELLS) + CELLS.append(new_generation(CELLS, rule, time)) + img = generate_image(CELLS) + # Uncomment for saving the image + # img.save(f"rule_{rule_num}.png") + img.show() From 81103446a612b1cea33a1938a9858468a29ac64c Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 26 Apr 2020 02:48:25 +0200 Subject: [PATCH 09/10] Update one_dimensional.py --- cellular_automata/one_dimensional.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index ac34a97b153e..6f03ca509e7c 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -28,18 +28,12 @@ def format_ruleset(ruleset: int) -> List[int]: def new_generation(cells: List[List[int]], rule: List[int], time: int) -> List[int]: + population = len(cells[0]) # 31 next_generation = [] - for i in range(31): + for i in range(population): # Get the neighbors of each cell - if i == 0: # leftmost cell - left_neighbor = 0 - right_neighbor = cells[time][i + 1] - elif i == 30: # rightmost cell - left_neighbor = cells[time][i - 1] - right_neighbor = 0 - else: # All other cells - left_neighbor = cells[time][i - 1] - right_neighbor = cells[time][i + 1] + left_neighbor = 0 if i == 0 else cells[time][i - 1] # special: leftmost cell + right_neighbor = 0 if i = population - 1 else cells[time][i + 1] # rightmost # Define a new cell and add it to the new generation situation = 7 - int(f"{left_neighbor}{cells[time][i]}{right_neighbor}", 2) next_generation.append(rule[situation]) @@ -74,6 +68,6 @@ def generate_image(cells: List[List[int]]) -> Image.Image: for time in range(16): CELLS.append(new_generation(CELLS, rule, time)) img = generate_image(CELLS) - # Uncomment for saving the image + # Uncomment to save the image # img.save(f"rule_{rule_num}.png") img.show() From faa158caca5daeca3aaee7141adc0291f5191b55 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 26 Apr 2020 02:54:48 +0200 Subject: [PATCH 10/10] Update one_dimensional.py --- cellular_automata/one_dimensional.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cellular_automata/one_dimensional.py b/cellular_automata/one_dimensional.py index 6f03ca509e7c..98d6fa25d7f5 100644 --- a/cellular_automata/one_dimensional.py +++ b/cellular_automata/one_dimensional.py @@ -33,7 +33,7 @@ def new_generation(cells: List[List[int]], rule: List[int], time: int) -> List[i for i in range(population): # Get the neighbors of each cell left_neighbor = 0 if i == 0 else cells[time][i - 1] # special: leftmost cell - right_neighbor = 0 if i = population - 1 else cells[time][i + 1] # rightmost + right_neighbor = 0 if i == population - 1 else cells[time][i + 1] # rightmost # Define a new cell and add it to the new generation situation = 7 - int(f"{left_neighbor}{cells[time][i]}{right_neighbor}", 2) next_generation.append(rule[situation])