根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
2. 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
3. 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
4. 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上细胞的下一个(一次更新后的)状态。
进阶:
- 你可以使用原地算法解题吗?请记住,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值更新其他格子。
- 在此题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
关于这个题的代码和注释
class Solution(object):
def gameOfLife(self, board):
"""
:type board: List[List[int]]
:rtype: void Do not return anything, modify board in-place instead.
"""
# 那么我们分析,是不是可以使用原数组缓存结果。但又不影响后续计算。因为所有数组的值只有两个,1:存活,0:死亡。
# 那么我们就可以用二进制11,表示当前状态存活,下一个状态存活。3
# 01:表示当前状态存活,下一个状态死亡1
# 10:表示当前状态死亡,下一个状态存活。2
# 00:当前状态死亡,下一个状态存活。0
m = len(board)
n = len(board[0]) if m else 0
for i in range(m):
for j in range(n):
# 每次需要重新统计刷新
count = 0
## Count live cells in 3x3 block.
# // 统计为1的邻居个数,包括自己
# 用max是为了防止边界条件
# min也是为了边界条件
for I in range(max(i-1, 0), min(i+2, m)):
for J in range(max(j-1, 0), min(j+2, n)):
# board[I][J] & 1表示当前细胞是活的
count += board[I][J] & 1
# if (count == 4 && board[i][j]) means:
# Any live cell with three live neighbors lives.
# if (count == 3) means:
# Any live cell with two live neighbors.
# Any dead cell with exactly three live neighbors lives.
# if (count == 4 && board[i][j]) means:邻居个数为3,count=3说明邻居个数为2
# 什么情况下当前的细胞一定是活着的,1,我和所有的邻居个数和为4,并且我一定活着
# 2.我和邻居的个数合为3,包括我死了,邻居为3,我活着,邻居为2
# 判断下一个细胞是活着的状态,包括当前的状态和下一个状态
if (count == 4 and board[i][j]) or count == 3:
# 10:表示当前状态死亡,下一个状态存活。
# 如果当前细胞是死的00,或者01或上10为10或者11,表示2或者3.
board[i][j] |= 2 # Mark as live.
for i in range(m):
for j in range(n):
# 向右移动表示下一个状态
board[i][j] >>= 1 # Update to the next state.a
from numpy import random
if __name__ == "__main__":
height= random.randint(0,2,size=(9,15))
Solution().gameOfLife(height.tolist())