Conway's game of life neighbor count

Viewed 4276
def neighbors(matrix, r, c):

    live_neighbors = 0

    if matrix[r][c-1] != 0:
        live_neighbors += 1
    if matrix[r-1][c] != 0:
        live_neighbors += 1
    if matrix[r-1][c+1] != 0:
        live_neighbors += 1
    if matrix[r][c-1] != 0:
        live_neighbors += 1
    if matrix[r][c+1] != 0:
        live_neighbors += 1
    if matrix[r+1][c-1] != 0:
        live_neighbors += 1
    if matrix[r+1][c] != 0:
        live_neighbors += 1
    if matrix[r+1][c+1] != 0:
        live_neighbors += 1

    return live_neighbors

This is the code I have written so far. How do I count the neighbors of the border cells? If I use this code I would get an index out of range error.

2 Answers

You can use a helper function to check for boundaries:

def neighbors(matrix, r, c):
    def get(r, c):
        return 0 <= r < len(matrix) and 0 <= c < len(matrix[r]) and matrix[r][c]

    live_neighbors = 0

    if get(r, c-1) != 0:
        live_neighbors += 1
    if get(r-1, c) != 0:
        live_neighbors += 1
    if get(r-1, c+1) != 0:
        live_neighbors += 1
    if get(r, c-1) != 0:
        live_neighbors += 1
    if get(r, c+1) != 0:
        live_neighbors += 1
    if get(r+1, c-1) != 0:
        live_neighbors += 1
    if get(r+1, c) != 0:
        live_neighbors += 1
    if get(r+1, c+1) != 0:
        live_neighbors += 1

    return live_neighbors

You can also use itertools.product in a generator expression for sum instead of if statements to count all the live neighbors:

from itertools import product
def neighbors(matrix, r, c):
    def get(r, c):
        return 0 <= r < len(matrix) and 0 <= c < len(matrix[r]) and matrix[r][c]
    return sum(get(r + i, c + j) for i, j in product(range(-1, 2), 2) if i or j)

A possible solution without all those if statements:

def neighbors(matrix, r, c):
    def get(r, c):
        if 0 <= r < len(matrix) and 0 <= c < len(matrix[r]):
            return matrix[r][c]
        else:
            return 0

    neighbors_list = [get(r-1, c-1), get(r-1, c), get(r-1, c+1),
                      get(r  , c-1),              get(r  , c+1),
                      get(r+1, c-1), get(r+1, c), get(r+1, c+1)]

    return sum(map(bool, neighbors_list))

matrix = [ [0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1],
           [0, 0, 0, 1, 1],
           [0, 0, 0, 1, 1],
           [0, 0, 1, 1, 1] ]

print(neighbors(matrix, 0, 0))  # 0
print(neighbors(matrix, 1, 2))  # 1
print(neighbors(matrix, 3, 2))  # 4
print(neighbors(matrix, 4, 4))  # 3

In case the cells would only have values either 0 or 1, the neighbors function would simply return sum(neighbors_list).

Related