Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting Neighbors in Matrix - Conway Game of Life

For each matrix element, I want to add the values of all its neighbor cells.

Starting with my initial array

board = np.array([[0, 1, 1],
                   [0, 1, 0],
                   [1, 0, 0]])

My result should be:

([2,2,2],
 [3,3,3],
 [1,2,1])

I created a function and used a brute force method to find whether or not a cell exists in its surrounding. If it does, add up the values and return the total. I'm not sure if I'm approaching my if statements correctly. It's saying the following error

'The truth value of an array with more than one element is ambiguous: Use a.any() or a.all()'

def count_living_neighbors(board):
    count = np.zeros(board.shape, dtype=int)
    #
    # YOUR CODE HERE
    #

    for row in range(len(board)):
        for column in range(len(board[row])):
            total = 0
            if (board[column - 1]).any() in board:
                total += board[row][column-1]
            if (board[column + 1]).any() in board:
                total += board[row][column+1]    
            if (board[row - 1]).any() in board:
                total += board[row-1][column]
            if (board[row + 1]).any() in board:
                total += board[row+1][column]
            if (board[row + 1] and board[column - 1]).any() in board:
                total += board[row+1][column-1]
            if (board[row - 1] and board[column - 1]).any() in board:
                total += board[row-1][column-1]
            if (board[row + 1] and board[column + 1]).any() in board:
                total += board[row+1][column+1]
            if (board[row - 1] and board[column + 1]).any() in board:
                total += board[row+1][column+1]

            count[row][column] = total         

    return count
like image 440
GenXeral Avatar asked Oct 29 '22 23:10

GenXeral


1 Answers

You can use scipy.signal.convolve with mode='same':

from scipy import signal

kernel = np.ones((3, 3), dtype=np.int8)
kernel[1, 1] = 0
print(signal.convolve(board, kernel, mode='same'))
[[2 2 2]
 [3 3 3]
 [1 2 1]]

Here kernel looks like this:

array([[1, 1, 1],
       [1, 0, 1],
       [1, 1, 1]], dtype=int8)

and will be the same regardless of the shape of board. Basically, kernel is referring to the positions of the neighbors (relative to the 0 in the center).

like image 85
Brad Solomon Avatar answered Nov 15 '22 07:11

Brad Solomon