import numpy as np

Z =  np.random.randint(2, size=(10, 10))
print("input")
print(Z)
def compute_neigbours(Z):
    shape = len(Z), len(Z[0])
    N  = [[0,]*(shape[0])  for i in range(shape[1])]
    for x in range(1,shape[0]-1):
        for y in range(1,shape[1]-1):
            N[x][y] = Z[x-1][y-1]+Z[x][y-1]+Z[x+1][y-1] \
                    + Z[x-1][y]+Z[x+1][y]   \
                    + Z[x-1][y+1]+Z[x][y+1]+Z[x+1][y+1]
    return N

def iterate(Z):
    N = compute_neigbours(Z)
    for x in range(1,Z.shape[0]-1):
        for y in range(1,Z.shape[1]-1):
             if Z[x][y] == 1 and (N[x][y] < 2 or N[x][y] > 3): #death
                 Z[x][y] = 0
             elif Z[x][y] == 1 and (N[x][y] == 2 or N[x][y] == 3):  # survive
                     Z[x][y] = 1
             elif Z[x][y] == 0 and N[x][y] == 3: #birth
                 Z[x][y] = 1
    return Z

for i in range(4):
    iterate(Z)

print("Output")
print(Z)