Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Bingo in Numpy array

Say I have a matrix

import numpy as np
A = np.array([[ 1,  2,  3,  4],
              [ 5,  6,  7,  8],
              [ 9, 10, 11, 12],
              [13, 14, 15, 16]])

I want to check if an 1D array is included in this matrix horizontally, vertically or diagonally. Below is the code that I came up with

def bingo(a, A):
    return np.max(np.diff(np.argwhere(np.isin(A, a)).T))

a1 = np.array([3, 4])
a2 = np.array([1, 5, 9])
a3 = np.array([5, 10, 15])
a4 = np.array([13, 10, 7, 4])
assert bingo(a1, A) == bingo(a2, A) == bingo(a3, A) == bingo(a4, A) == True

However, there are 3 major issues with my code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  1. I don’t want to consider the reverse case, which my code does. For example, np.array([4, 3, 2, 1]) should not be considered as being included in the matrix A.

  2. My code won’t work if the array only contains 1 element. For example, np.array([1]) should be considered as being included in the matrix A.

  3. My code won’t work if the matrix A contains duplicate elements.

Can anyone suggest a general and numpyic way to do this?

>Solution :

You need to test the rows, the columns and the two diagonals.

All individual cases are easy to perform, you can then combine them with or to have lazy evaluation (i.e., evaluation stops as soon as one match is found):

import numpy as np
A = np.array([[ 1,  2,  3,  4],
              [ 5,  6,  7,  8],
              [ 9, 10, 11, 12],
              [13, 14, 15, 16]])

def bingo(A, test):
    return (# rows
            (A == test).all(1).any()
            # cols
            or (A.T == test).all(1).any()
            # first diagonal
            or (test == A.diagonal()).all()
            # second diagonal
            or (test == np.fliplr(A.T).diagonal()).all()
            )

bingo(A, [1,2,3,4])    # True

bingo(A, [1,2,4,3])    # False

bingo(A, [2,6,10,14])  # True

bingo(A, [4,3,2,1])    # False 

bingo(A, [1,6,11,16])  # True

bingo(A, [13,10,7,4])  # True
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading