元胞自动机(CA)是自动机理论研究的离散计算模型。细胞自动机在许多领域都有应用,包括物理学、理论生物学和微观结构建模。
元胞自动机由一个规则的单元格网格组成,每个单元格处于有限数量的状态之一,例如开和关。网格可以有任意数量的维度。对于每个单元格,相对于指定的单元格定义了一组称为其邻域的单元格。通过为每个单元格分配一个状态来选择初始状态(时间t = 0)。根据某些固定的规则(通常是数学函数)创建新一代(将t前进1),该规则根据单元的当前状态及其邻近单元的状态确定每个单元的新状态。通常情况下,更新单元格状态的规则对每个单元格是相同的,不会随着时间的推移而改变,并同时应用于整个网格。 20世纪40年代,斯坦尼斯劳·乌兰和约翰·冯·诺伊曼在洛斯阿拉莫斯国家实验室(Los Alamos National Laboratory)发现了这个概念。虽然在20世纪50年代和60年代,一些人一直在研究这个问题,但直到20世纪70年代,康威的二维细胞自动机《生命的游戏》问世,人们对这个课题的兴趣才扩展到学术界之外。20世纪80年代,斯蒂芬·沃尔夫拉姆(Stephen Wolfram)从事了一维细胞自动机的系统研究,他称之为基本细胞自动机;他的研究助理马修·库克证明了其中一条规则是图灵完备的。
细胞自动机的主要分类,编号为1到4。它们依次是:模式通常稳定为同质的自动机,模式演变为基本稳定或振荡结构的自动机,模式以一种看似混乱的方式演变的自动机,以及模式变得极其复杂并可能持续很长时间的自动机,具有稳定的局部结构。
最后一类被认为在计算上是通用的,或者说能够模拟图灵机。
模拟二维元胞自动机的一种方法是设想一张大的网格以及一组让细胞遵循的规则。每个方块被称为“细胞”,每个细胞有两种可能的状态,黑和白。细胞的邻域是相邻的细胞。两种最常见的社区类型是由四个正交相邻的细胞组成邻域以及四个对角相邻的单元。对于这样一个单元格及其邻域,有512(= $2^9$)种可能的模式。对于512种可能的模式中的每一种,规则表将说明在下一个时间间隔中中心单元格是黑还是白。康威的生命游戏是这个模型的一个流行版本。另一种常见的邻域类型是扩展的von Neumann邻域,它包括每个正交方向上最近的两个单元,共8个。这种规则系统的一般方程是$k^{k^s}$,其中k是一个单元格可能状态的数量,s是用于确定该单元格下一个状态的相邻单元格(包括要计算的单元格本身)的数量因此,在具有摩尔邻域的二维系统中,可能的自动机总数将是$2^{2^9}$,或1.34×$10^{154}$。
通常认为,每个细胞开始时的状态都是相同的,只有少数细胞处于其他状态;状态值的分配称为配置更普遍的说法是,有时假设一开始就有一个周期性的模式,只有有限数量的细胞违反了这个模式。后一种假设在一维元胞自动机中很常见。
20世纪40年代,Stanislaw Ulam在洛斯阿拉莫斯国家实验室工作时,用一个简单的晶格网络作为模型,研究了晶体的生长与此同时,乌拉姆在洛斯阿拉莫斯的同事约翰·冯·诺伊曼(John von Neumann)正在研究自我复制系统的问题冯·诺伊曼最初的设计是基于一个机器人制造另一个机器人的概念。这种设计被称为运动学模型。在开发这个设计时,冯·诺伊曼开始意识到制造一个自我复制机器人的巨大困难,以及为机器人提供“大量零件”来制造它的复制体的巨大成本。诺伊曼在1948年的Hixon研讨会上写了一篇题为“自动机的一般和逻辑理论”的论文乌拉姆是建议使用离散系统来创建自我复制的简化模型的人。Nils Aall Barricelli对这些人造生命模型进行了许多最早的探索。
乌拉姆和冯·诺伊曼在20世纪50年代末发明了一种计算液体运动的方法。该方法的驱动概念是将液体视为一组离散单元,并根据其相邻单元的行为计算每个单元的运动第一个细胞自动机系统就这样诞生了。和乌拉姆的晶格网络一样,冯·诺伊曼的细胞自动机也是二维的,通过算法实现了自我复制。结果是一个通用的复制器和构造器在一个具有小邻域的细胞自动机中工作(只有那些接触的细胞是邻域;对于von Neumann的细胞自动机,只有正交细胞),并且每个细胞有29个状态。冯·诺伊曼通过设计一个20万个细胞结构来证明一种特定的模式可以在给定的细胞宇宙中无限复制自己。这种设计被称为镶嵌模型,被称为冯·诺依曼通用构造器。
同样在20世纪40年代,诺伯特·维纳(Norbert Wiener)和阿图罗·罗森布鲁斯(Arturo Rosenblueth)开发了一种具有细胞自动机某些特征的可兴奋介质模型他们的具体动机是对心脏系统脉冲传导的数学描述。但是他们的模型不是元胞自动机,因为信号传播的介质是连续的,波前是曲线。1978年,J. M. Greenberg和S. P. Hastings建立并研究了可激发介质的真元胞自动机模型;参见格林伯格-黑斯廷斯元胞自动机。Wiener和Rosenblueth的原始工作包含了许多见解,并继续被引用在关于心律失常和兴奋系统的现代研究出版物中
在20世纪60年代,细胞自动机作为一种特殊的动力系统被研究,并首次与符号动力学的数学领域建立了联系。1969年,Gustav a. Hedlund根据这一观点编制了许多结果,这篇论文至今仍被认为是细胞自动机数学研究的开创性论文。最基本的结果是在curtis - hedlundd - lyndon定理中将元胞自动机的全局规则集刻画为移位空间的连续自同构集。
1969年,德国计算机先驱康拉德·祖泽(Konrad Zuse)出版了《计算空间》一书,提出宇宙的物理定律本质上是离散的,整个宇宙是单个元胞自动机上确定性计算的输出;“祖斯的理论”成为数字物理学研究领域的基础
同样是在1969年,计算机科学家Alvy Ray Smith完成了斯坦福大学的一篇关于细胞自动机理论的博士论文,这是第一次将CA作为计算机的一般类别进行数学处理。许多论文都来自这篇论文:他证明了各种形状的邻域的等价性,如何化简摩尔邻域为冯·诺依曼邻域,或如何化简任何邻域为冯·诺依曼邻域。他证明了二维CA是计算通用的,引入了一维CA,并表明它们也是计算通用的,即使具有简单的邻域他展示了如何将复杂的von Neumann证明的构造普适性(以及自复制机器)纳入到一维CA计算普适性的结果中。作为von Neumann关于CA的书的德语版的介绍,他写了一份该领域的调查,参考了几十篇论文,来自许多国家的许多作者在十年左右的工作中,经常被现代CA研究人员忽视
20世纪70年代,一种名为Game of Life的双状态二维细胞自动机广为人知,尤其是在早期的计算社区中。由约翰·康威发明,马丁·加德纳在《科学美国人》的一篇文章中推广,规则如下:
Wolfram在《一种新型科学》和20世纪80年代中期的几篇论文中,根据细胞自动机和其他一些简单的计算模型的行为,定义了四种类型。细胞自动机的早期研究倾向于识别特定规则的模式类型,Wolfram的分类是对规则本身进行分类的第一次尝试。按复杂性排序,这些类是:
第2类稳定或振荡结构可能是最终结果,但达到这种状态所需的步骤可能非常多,即使初始模式相对简单。最初模式的局部变化可能会无限扩散。Wolfram推测,许多4类细胞自动机(如果不是全部的话)都能够进行通用计算。
受Wolfram分类法的启发,已经有人尝试将细胞自动机按照严格的形式分类。例如,Culik和Yu提出了三个定义良好的类(以及第四个不匹配这些自动机的类),它们有时被称为Culik-Yu类;这些组织的成员资格被证明是无法确定的。Wolfram的第2类可以被分成两组,分别是稳定的(定点的)和振荡的(周期性的)规则
有4类动力系统的想法最初来自诺贝尔奖获得者化学家伊利亚·普里戈因,他确定了这4类热力系统(1)热力学平衡系统,(2)空间/时间均匀系统,(3)混沌系统,(4)复杂的远离平衡的耗散结构系统(见Nicolis论文中的图1(普里戈因的学生))
元胞自动机的概念有许多可能的推广。
一种方法是使用矩形(立方等)以外的网格。例如,如果一个平面用正六边形平铺,这些六边形可以用作单元格。在许多情况下,得到的元胞自动机等价于具有特殊设计的邻域和规则的矩形网格。另一种变体是使网格本身不规则。
此外,规则可以是概率的,而不是确定性的。这种元胞自动机称为概率元胞自动机。一个概率规则给出了,对于t时刻的每种模式,中心细胞在t + 1时刻转变到每种可能状态的概率。有时使用更简单的规则;例如:“规则就是生命游戏,但在每个时间步中,每个细胞转变成相反颜色的概率为0.001%。”
邻里关系或规则会随着时间或空间的变化而变化。例如,最初一个细胞的新状态可以由水平相邻的细胞决定,但对于下一代来说,将使用垂直的细胞。
在细胞自动机中,一个细胞的新状态不受其他细胞的新状态影响。这可以改变,例如,一个2 × 2的单元格块可以由它自己和相邻的单元格确定。
有连续的自动机。它们类似于整体细胞自动机,但不是规则和状态是离散的(例如,一个表,使用状态{0,1,2}),而是使用连续函数,状态变为连续的(通常值为[0,1])。位置的状态是有限数量的实数。某些细胞自动机可以以这种方式产生液体模式的扩散。
连续空间自动机具有连续的位置。位置的状态是有限数量的实数。时间也是连续的,状态根据微分方程演化。一个重要的例子是反应-扩散纹理,这是艾伦·图灵提出的微分方程,用来解释化学反应如何产生斑马身上的条纹和豹子身上的斑点当这些被元胞自动机近似时,它们通常会产生相似的模式。MacLennan将连续空间自动机作为计算模型。
有一些已知的连续空间自动机的例子,它们展示了类似于生命游戏中的滑翔机的传播现象
最简单的非平凡细胞自动机是一维的,每个细胞有两种可能的状态,细胞的邻居定义为相邻细胞的两侧。一个单元格和它的两个相邻单元格组成一个由3个单元格组成的邻域,因此邻域有$2^3 = 8$种可能的模式。规则由决定每个模式的单元格在下一代中是1还是0组成。那么就有$2^8 = 256$个可能的规则.
这256个元胞自动机通常引用Wolfram代码,Wolfram代码是Wolfram发明的一种标准命名约定,为每个规则提供从0到255的数字。许多论文对这256个元胞自动机进行了分析和比较。规则30、规则90、规则110和规则184细胞自动机特别有趣。下面的图像显示了规则30和110的历史,当初始配置由1(在每个图像的顶部)和0包围时。每一行像素代表自动机历史上的一代,t=0是最上面一行。每个像素用白色表示0,黑色表示1。
一基本等元胞自动机规则由8位指定,所有基本元胞自动机规则都可以被认为位于8维单位超立方体的顶点上。这个单位超立方就是元胞自动机规则空间。对于次近邻元胞自动机,规则由$2^5 = 32$位指定,元胞自动机规则空间为32维单位超立方体。两个规则之间的距离可以通过从一个顶点(代表第一个规则)到另一个顶点(代表另一个规则)沿着超立方体的边缘移动所需的步数来定义。这种规则与规则之间的距离也被称为汉明距离。
元胞自动机规则空间允许我们问这样一个问题:具有相似动力学行为的规则是否彼此“接近”。在二维平面上图形化地绘制高维超立方体仍然是一项艰巨的任务,超立方体中规则的一个粗略定位器是基本规则的8位字符串(或下最近邻规则的32位字符串)中位-1的数量。在规则空间的这些片中绘制不同Wolfram类中的规则,表明第1类规则倾向于具有较少的位-1数量,因此位于空间的一个区域,而第3类规则倾向于具有较高的位-1比例(50%)
对于较大的元胞自动机规则空间,表明第4类规则位于第1类和第3类规则之间。这一观察结果是混沌边缘这一短语的基础,并使人联想到热力学中的相变。
参考资料:
import time
import os
import random
import sys
def clear_console():
"""
Clears the console using a system command based on the user's operating system.
"""
if sys.platform.startswith('win'):
os.system("cls")
elif sys.platform.startswith('linux'):
os.system("clear")
elif sys.platform.startswith('darwin'):
os.system("clear")
else:
print("Unable to clear terminal. Your operating system is not supported.\n\r")
def resize_console(rows, cols):
"""
Re-sizes the console to the size of rows x columns
:param rows: Int - The number of rows for the console to re-size to
:param cols: Int - The number of columns for the console to re-size to
"""
if cols < 32:
cols = 32
if sys.platform.startswith('win'):
command = "mode con: cols={0} lines={1}".format(cols + cols, rows + 5)
os.system(command)
elif sys.platform.startswith('linux'):
command = "\x1b[8;{rows};{cols}t".format(rows=rows + 3, cols=cols + cols)
sys.stdout.write(command)
elif sys.platform.startswith('darwin'):
command = "\x1b[8;{rows};{cols}t".format(rows=rows + 3, cols=cols + cols)
sys.stdout.write(command)
else:
print("Unable to resize terminal. Your operating system is not supported.\n\r")
def create_initial_grid(rows, cols):
"""
Creates a random list of lists that contains 1s and 0s to represent the cells in Conway's Game of Life.
:param rows: Int - The number of rows that the Game of Life grid will have
:param cols: Int - The number of columns that the Game of Life grid will have
:return: Int[][] - A list of lists containing 1s for live cells and 0s for dead cells
"""
grid = []
for row in range(rows):
grid_rows = []
for col in range(cols):
# Generate a random number and based on that decide whether to add a live or dead cell to the grid
if random.randint(0, 7) == 0:
grid_rows += [1]
else:
grid_rows += [0]
grid += [grid_rows]
return grid
def print_grid(rows, cols, grid, generation):
"""
Prints to console the Game of Life grid
:param rows: Int - The number of rows that the Game of Life grid has
:param cols: Int - The number of columns that the Game of Life grid has
:param grid: Int[][] - The list of lists that will be used to represent the Game of Life grid
:param generation: Int - The current generation of the Game of Life grid
"""
clear_console()
# A single output string is used to help reduce the flickering caused by printing multiple lines
output_str = ""
# Compile the output string together and then print it to console
output_str += "Generation {0} - To exit the program press <Ctrl-C>\n\r".format(generation)
for row in range(rows):
for col in range(cols):
if grid[row][col] == 0:
output_str += ". "
else:
output_str += "@ "
output_str += "\n\r"
print(output_str, end=" ")
def create_next_grid(rows, cols, grid, next_grid):
"""
Analyzes the current generation of the Game of Life grid and determines what cells live and die in the next
generation of the Game of Life grid.
:param rows: Int - The number of rows that the Game of Life grid has
:param cols: Int - The number of columns that the Game of Life grid has
:param grid: Int[][] - The list of lists that will be used to represent the current generation Game of Life grid
:param next_grid: Int[][] - The list of lists that will be used to represent the next generation of the Game of Life
grid
"""
for row in range(rows):
for col in range(cols):
# Get the number of live cells adjacent to the cell at grid[row][col]
live_neighbors = get_live_neighbors(row, col, rows, cols, grid)
# If the number of surrounding live cells is < 2 or > 3 then we make the cell at grid[row][col] a dead cell
if live_neighbors < 2 or live_neighbors > 3:
next_grid[row][col] = 0
# If the number of surrounding live cells is 3 and the cell at grid[row][col] was previously dead then make
# the cell into a live cell
elif live_neighbors == 3 and grid[row][col] == 0:
next_grid[row][col] = 1
# If the number of surrounding live cells is 3 and the cell at grid[row][col] is alive keep it alive
else:
next_grid[row][col] = grid[row][col]
def get_live_neighbors(row, col, rows, cols, grid):
"""
Counts the number of live cells surrounding a center cell at grid[row][cell].
:param row: Int - The row of the center cell
:param col: Int - The column of the center cell
:param rows: Int - The number of rows that the Game of Life grid has
:param cols: Int - The number of columns that the Game of Life grid has
:param grid: Int[][] - The list of lists that will be used to represent the Game of Life grid
:return: Int - The number of live cells surrounding the cell at grid[row][cell]
"""
life_sum = 0
for i in range(-1, 2):
for j in range(-1, 2):
# Make sure to count the center cell located at grid[row][col]
if not (i == 0 and j == 0):
# Using the modulo operator (%) the grid wraps around
life_sum += grid[((row + i) % rows)][((col + j) % cols)]
return life_sum
def grid_changing(rows, cols, grid, next_grid):
"""
Checks to see if the current generation Game of Life grid is the same as the next generation Game of Life grid.
:param rows: Int - The number of rows that the Game of Life grid has
:param cols: Int - The number of columns that the Game of Life grid has
:param grid: Int[][] - The list of lists that will be used to represent the current generation Game of Life grid
:param next_grid: Int[][] - The list of lists that will be used to represent the next generation of the Game of Life
grid
:return: Boolean - Whether the current generation grid is the same as the next generation grid
"""
for row in range(rows):
for col in range(cols):
# If the cell at grid[row][col] is not equal to next_grid[row][col]
if not grid[row][col] == next_grid[row][col]:
return True
return False
def get_integer_value(prompt, low, high):
"""
Asks the user for integer input and between given bounds low and high.
:param prompt: String - The string to prompt the user for input with
:param low: Int - The low bound that the user must stay within
:param high: Int - The high bound that the user must stay within
:return: The valid input value that the user entered
"""
while True:
try:
value = int(input(prompt))
except ValueError:
print("Input was not a valid integer value.")
continue
if value < low or value > high:
print("Input was not inside the bounds (value <= {0} or value >= {1}).".format(low, high))
else:
break
return value
def run_game():
"""
Asks the user for input to setup the Game of Life to run for a given number of generations.
"""
clear_console()
# Get the number of rows and columns for the Game of Life grid
rows = get_integer_value("Enter the number of rows (10-60): ", 10, 60)
clear_console()
cols = get_integer_value("Enter the number of cols (10-118): ", 10, 118)
# Get the number of generations that the Game of Life should run for
generations = 5000
resize_console(rows, cols)
# Create the initial random Game of Life grids
current_generation = create_initial_grid(rows, cols)
next_generation = create_initial_grid(rows, cols)
# Run Game of Life sequence
gen = 1
for gen in range(1, generations + 1):
if not grid_changing(rows, cols, current_generation, next_generation):
break
print_grid(rows, cols, current_generation, gen)
create_next_grid(rows, cols, current_generation, next_generation)
time.sleep(1 / 5.0)
current_generation, next_generation = next_generation, current_generation
print_grid(rows, cols, current_generation, gen)
return input("<Enter> to exit or r to run again: ")
# Start the Game of Life
run = "r"
while run == "r":
out = run_game()
run = out
Enter the number of rows (10-60): 10 Enter the number of cols (10-118): 10 Generation 1 - To exit the program press <Ctrl-C> . . . . @ . . . @ @ . @ . . . @ . @ . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . @ . . . . . . @ . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . @ . . . . Generation 2 - To exit the program press <Ctrl-C> . . . . @ @ @ . @ . . . . . @ . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 3 - To exit the program press <Ctrl-C> . . . . @ @ . @ . . . . . . @ . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . Generation 4 - To exit the program press <Ctrl-C> . . . . @ @ . . . . . . . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . . Generation 5 - To exit the program press <Ctrl-C> . . . @ . . . . . . . . . . @ . @ . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . @ . @ . . . Generation 6 - To exit the program press <Ctrl-C> . . . @ @ . . . . . . . . . @ @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . @ @ . . . . Generation 7 - To exit the program press <Ctrl-C> . . . @ . . . . . . . . . @ . @ . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . @ . @ . . . . Generation 8 - To exit the program press <Ctrl-C> . . @ @ . . . . . . . . . @ . @ . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . . @ . @ . . . . Generation 9 - To exit the program press <Ctrl-C> . . @ @ . . . . . . . . @ @ . @ . . . . . . . . @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ . . . . . . @ @ . @ . . . . Generation 10 - To exit the program press <Ctrl-C> . @ . . . . . . . . . . @ . . @ . . . . . . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . . . . . @ . . @ . . . . Generation 11 - To exit the program press <Ctrl-C> . @ @ . . . . . . . . . @ @ . @ . . . . . . . @ @ @ . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . @ @ @ . . . . . . @ @ . @ . . . . Generation 12 - To exit the program press <Ctrl-C> . @ . . . . . . . . . @ . . . @ . . . . . . @ . . @ . . . . . . . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ @ @ . . . . . . @ . . @ . . . . . @ . . . @ . . . . Generation 13 - To exit the program press <Ctrl-C> @ @ @ . . . . . . . . @ @ . . . . . . . . . @ @ . @ @ . . . . . . @ @ @ . . . . . . . . @ . . . . . . . . . . . . . . . . . . . @ . . . . . . . . @ @ @ . . . . . . @ @ . @ @ . . . . @ @ . . . . . . . Generation 14 - To exit the program press <Ctrl-C> @ . . @ . . . . . . @ . . . . . . . . . . @ . . . @ @ . . . . . @ . . . @ . . . . . . @ @ @ . . . . . . . . . . . . . . . . . @ @ @ . . . . . . @ . . . @ . . . . @ . . . @ @ . . . @ . . . . . . . . . Generation 15 - To exit the program press <Ctrl-C> @ @ . . . . . . . @ @ @ . . . . . . . . . @ . . . @ @ . . . . . @ @ . . @ . . . . . . @ @ @ . . . . . . . . . . . . . . . . . @ @ @ . . . . . . @ @ . . @ . . . . @ . . . @ @ . . . @ @ . . . . . . . . Generation 16 - To exit the program press <Ctrl-C> . . @ . . . . . . @ . . @ . . . . . . @ @ @ . . . @ @ . . . . . @ @ . . @ . . . . . @ @ @ @ . . . . . . . . . . . . . . . . @ @ @ @ . . . . . . @ @ . . @ . . . @ @ . . . @ @ . . . . . @ . . . . . . @ Generation 17 - To exit the program press <Ctrl-C> @ @ @ @ . . . . @ @ . . @ . . . . . . @ @ @ . @ . @ @ . . . . . . . . . @ . . . . . @ . @ @ . . . . . . . . . . . . . . . . @ . @ @ . . . . . . . . . . @ . . . @ @ . @ . @ @ . . . . . @ . . . . . . @ Generation 18 - To exit the program press <Ctrl-C> . . . @ . . . . @ . . . . . @ . . . @ . @ @ @ . . @ @ . . . . @ @ @ . . @ . . . . . . . . @ . . . . . . . . . . . . . . . . . . . @ . . . . . @ @ @ . . @ . . . @ @ @ . . @ @ . . . . . . . @ . . . @ . Generation 19 - To exit the program press <Ctrl-C> . . . @ @ . . @ @ @ . @ @ @ @ @ . @ . @ @ . . . @ @ @ @ . . @ . . @ @ . @ . . . . . @ . . . . . . . . . . . . . . . . . . . @ . . . . . . . @ . . @ @ . @ . . . @ . . . @ @ @ @ . . . @ @ @ @ @ . @ . @ Generation 20 - To exit the program press <Ctrl-C> . . . . . . . @ . @ . @ @ . . . . . . @ @ . . . . . . @ @ @ . @ . @ @ . @ @ . . . . . @ . . . . . . . . . . . . . . . . . . . @ . . . . . . . @ . @ @ . @ @ . . @ . . . . . . @ @ @ . @ @ . . . . . . @ Generation 21 - To exit the program press <Ctrl-C> . . . . . . . . . @ . @ . . . . . @ . . . . . @ . . @ @ . @ @ . @ @ @ . @ @ . @ . . @ @ @ . . . . . . . . . . . . . . . . . @ @ @ . . . . . @ . @ @ @ . @ @ . @ . . . @ . . @ @ . @ . @ . . . . . @ . . Generation 22 - To exit the program press <Ctrl-C> @ . . . . . . . @ . @ . . . . . @ @ . . . @ . @ @ @ . . . @ @ @ . . . . @ @ . @ . @ @ . @ @ . . . . . . . . . . . . . . . @ @ . @ @ . . . . @ @ . . . . @ @ . @ . @ . @ @ @ . . . @ @ . . . . . @ @ . . Generation 23 - To exit the program press <Ctrl-C> @ @ . . . . . . @ . @ @ . . @ @ @ @ @ . . @ @ . @ @ . . . @ . . . . . . @ . @ @ . @ @ . . @ @ . . . . . . . . . . . . . . @ @ . . @ @ . . . . . . . . . @ . @ @ . @ @ . @ @ . . . @ @ @ . . @ @ @ @ @ . Generation 24 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . . @ @ . @ @ @ . . @ @ @ @ . . . . . . . . @ @ . @ @ @ @ . . . . . @ @ @ . . . . . . . . . . . . . . . . . @ @ @ . . . . . @ @ . @ @ @ @ . @ @ @ @ . . . . . . . . @ @ . @ @ @ . Generation 25 - To exit the program press <Ctrl-C> . . @ . . . . . . . . @ . . @ @ . @ . . . . . . . . . . . @ . . . . . . . . @ . . . . . @ @ . . . . . . . . . . . . . . . . . . @ @ . . . . . . . . . . . . @ . . . . . . . . . . @ . @ . . @ @ . @ . . Generation 26 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . Generation 27 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 28 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 29 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 30 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 31 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 32 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 33 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 34 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 35 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 36 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 37 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 38 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 39 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 40 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 41 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 42 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 43 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 44 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 45 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 46 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 47 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 48 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 49 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 50 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 51 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 52 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 53 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 54 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 55 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 56 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 57 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 58 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 59 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 60 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 61 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 62 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 63 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 64 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 65 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 66 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 67 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 68 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 69 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 70 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 71 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 72 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 73 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 74 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 75 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 76 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 77 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 78 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 79 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 80 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 81 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 82 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 83 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 84 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 85 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 86 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 87 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 88 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 89 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 90 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 91 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 92 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 93 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 94 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 95 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 96 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 97 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 98 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 99 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 100 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 101 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 102 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 103 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 104 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 105 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 106 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 107 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 108 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 109 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 110 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 111 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 112 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 113 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . Generation 114 - To exit the program press <Ctrl-C> . @ @ @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generation 115 - To exit the program press <Ctrl-C> . . @ . . . . . . . . . @ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . .
---------------------------------------------------------------- KeyboardInterrupt Traceback (most recent call last) <ipython-input-2-d252d8b14c43> in <module> 217 run = "r" 218 while run == "r": --> 219 out = run_game() 220 run = out <ipython-input-2-d252d8b14c43> in run_game() 207 print_grid(rows, cols, current_generation, gen) 208 create_next_grid(rows, cols, current_generation, next_generation) --> 209 time.sleep(1 / 5.0) 210 current_generation, next_generation = next_generation, current_generation 211 KeyboardInterrupt:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib nbagg
from matplotlib import animation, rc, cm
import IPython, io, urllib
rc('animation', html='html5')
class LLCA:
"""
A Life Like Cellular Automaton (LLCA)
Inputs:
* C: a binary matrix representing the cells where 1 stands for alive and 0 for dead.
* rule: the rule of the in the format 'BXSY' where X and Y are the birth and survival conditions.
Example: GOL rule is "B3S23".
"""
def __init__(self, C = np.random.rand(50, 50), rule = "B3S23"):
self.C = np.array(C).astype(np.bool)
self.rule = rule
def parse_rule(self):
"""
Parses the rule string
"""
r = self.rule.upper().split("S")
B = np.array([int(i) for i in r[0][1:] ]).astype(np.int64)
S = np.array([int(i) for i in r[1] ]).astype(np.int64)
return B, S
def neighbors(self):
"""
Returns the number of living neigbors of each cell.
"""
C = self.C
N = np.zeros(C.shape, dtype = np.int8) # Neighbors matrix
N[ :-1, : ] += C[1: , : ] # Living cells south
N[ : , :-1] += C[ : ,1: ] # Living cells east
N[1: , : ] += C[ :-1, : ] # Living cells north
N[ : , 1: ] += C[ : , :-1] # Living cells west
N[ :-1, :-1] += C[1: ,1: ] # Living cells south east
N[1: , :-1] += C[ :-1,1: ] # Living cells north east
N[1: , 1: ] += C[ :-1, :-1] # Living cells north west
N[ :-1, 1: ] += C[1: , :-1] # Living cells south west
return N
def iterate(self):
"""
Iterates one time.
"""
B, S = self.parse_rule()
N = self.neighbors()
C = self.C
C1 = np.zeros(C.shape, dtype = np.int8)
for b in B: C1 += ((C == False) & (N == b))
for s in S: C1 += (C & (N == s))
self.C[:] = C1 > 0
# INITIAL CONFIGURATION
N = 100
t = np.linspace(0., 1., N+1)
X, Y = np.meshgrid(t, t)
f = 4
C0 = np.sin(2. * np.pi * f * X ) * np.sin(2. * np.pi * 2 * f * Y ) > -.1
g = LLCA(C0, rule = "B3S23")
# ANIMATION
def updatefig(*args):
g.iterate()
im.set_array(g.C)
return im,
fig, ax = plt.subplots()
ax.axis('off')
im = plt.imshow(g.C, interpolation = "nearest", cmap = cm.binary, animated=True)
#anim = animation.FuncAnimation(fig, updatefig, frames=200, interval=50, blit=True)
#plt.close()
#anim
#plt.show()
<ipython-input-4-da59444a2c42>:11: DeprecationWarning: `np.bool` is a deprecated alias for the builtin `bool`. To silence this warning, use `bool` by itself. Doing this will not modify any behavior and is safe. If you specifically wanted the numpy scalar type, use `np.bool_` here. Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations self.C = np.array(C).astype(np.bool)
import numpy as np
def life_step_1(X):
"""Game of life step using generator expressions"""
nbrs_count = sum(np.roll(np.roll(X, i, 0), j, 1)
for i in (-1, 0, 1) for j in (-1, 0, 1)
if (i != 0 or j != 0))
return (nbrs_count == 3) | (X & (nbrs_count == 2))
def life_step_2(X):
"""Game of life step using scipy tools"""
from scipy.signal import convolve2d
nbrs_count = convolve2d(X, np.ones((3, 3)), mode='same', boundary='wrap') - X
return (nbrs_count == 3) | (X & (nbrs_count == 2))
life_step = life_step_1
%pylab inline
# JSAnimation import available at https://github.com/jakevdp/JSAnimation
from JSAnimation.IPython_display import display_animation, anim_to_html
from matplotlib import animation
def life_animation(X, dpi=10, frames=10, interval=300, mode='loop'):
"""Produce a Game of Life Animation
Parameters
----------
X : array_like
a two-dimensional numpy array showing the game board
dpi : integer
the number of dots per inch in the resulting animation.
This controls the size of the game board on the screen
frames : integer
The number of frames to compute for the animation
interval : float
The time interval (in milliseconds) between frames
mode : string
The default mode of the animation. Options are ['loop'|'once'|'reflect']
"""
X = np.asarray(X)
assert X.ndim == 2
X = X.astype(bool)
X_blank = np.zeros_like(X)
figsize = (X.shape[1] * 1. / dpi, X.shape[0] * 1. / dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
ax = fig.add_axes([0, 0, 1, 1], xticks=[], yticks=[], frameon=False)
im = ax.imshow(X, cmap=plt.cm.binary, interpolation='nearest')
im.set_clim(-0.05, 1) # Make background gray
# initialization function: plot the background of each frame
def init():
im.set_data(X_blank)
return (im,)
# animation function. This is called sequentially
def animate(i):
im.set_data(animate.X)
animate.X = life_step(animate.X)
return (im,)
animate.X = X
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=frames, interval=interval)
#print anim_to_html(anim)
return display_animation(anim, default_mode=mode)
Populating the interactive namespace from numpy and matplotlib
np.random.seed(0)
X = np.zeros((30, 40), dtype=bool)
r = np.random.random((10, 20))
X[10:20, 10:30] = (r > 0.75)
life_animation(X, dpi=10, frames=40, mode='once')
D:\software_install\anaconda\lib\site-packages\JSAnimation\html_writer.py:281: MatplotlibDeprecationWarning: The 'clear_temp' parameter of setup() was deprecated in Matplotlib 3.3 and will be removed two minor releases later. If any parameter follows 'clear_temp', they should be passed as keyword, not positionally. super(HTMLWriter, self).setup(fig, outfile, dpi, <ipython-input-8-f55c6711e5bc>:5: DeprecationWarning: Calling np.sum(generator) is deprecated, and in the future will give a different result. Use np.sum(np.fromiter(generator)) or the python sum builtin instead. nbrs_count = sum(np.roll(np.roll(X, i, 0), j, 1)
---------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-9-bce5dd249975> in <module> 3 r = np.random.random((10, 20)) 4 X[10:20, 10:30] = (r > 0.75) ----> 5 life_animation(X, dpi=10, frames=40, mode='once') <ipython-input-8-f55c6711e5bc> in life_animation(X, dpi, frames, interval, mode) 65 66 #print anim_to_html(anim) ---> 67 return display_animation(anim, default_mode=mode) D:\software_install\anaconda\lib\site-packages\JSAnimation\IPython_display.py in display_animation(anim, **kwargs) 84 """Display the animation with an IPython HTML object""" 85 from IPython.display import HTML ---> 86 return HTML(anim_to_html(anim, **kwargs)) 87 88 D:\software_install\anaconda\lib\site-packages\JSAnimation\IPython_display.py in anim_to_html(anim, fps, embed_frames, default_mode) 72 #with tempfile.NamedTemporaryFile(suffix='.html') as f: 73 with _NameOnlyTemporaryFile(suffix='.html') as f: ---> 74 anim.save(f.name, writer=HTMLWriter(fps=fps, 75 embed_frames=embed_frames, 76 default_mode=default_mode)) D:\software_install\anaconda\lib\site-packages\matplotlib\animation.py in save(self, filename, writer, fps, dpi, codec, bitrate, extra_args, metadata, extra_anim, savefig_kwargs, progress_callback) 1143 progress_callback(frame_number, total_frames) 1144 frame_number += 1 -> 1145 writer.grab_frame(**savefig_kwargs) 1146 1147 def _step(self, *args): D:\software_install\anaconda\lib\contextlib.py in __exit__(self, type, value, traceback) 118 if type is None: 119 try: --> 120 next(self.gen) 121 except StopIteration: 122 return False D:\software_install\anaconda\lib\site-packages\matplotlib\animation.py in saving(self, fig, outfile, dpi, *args, **kwargs) 251 yield self 252 finally: --> 253 self.finish() 254 255 D:\software_install\anaconda\lib\site-packages\matplotlib\animation.py in finish(self) 516 # Call run here now that all frame grabbing is done. All temp files 517 # are available to be assembled. --> 518 self._run() 519 MovieWriter.finish(self) # Will call clean-up 520 D:\software_install\anaconda\lib\site-packages\JSAnimation\html_writer.py in _run(self) 321 of.write(JS_INCLUDE) 322 of.write(DISPLAY_TEMPLATE.format(id=self.new_id(), --> 323 Nframes=len(self._temp_names), 324 fill_frames=fill_frames, 325 interval=interval, AttributeError: 'HTMLWriter' object has no attribute '_temp_names'