Skip to content

Chapter 6 notebook: Straightforward translation of GoL rules using loops doesn't handle boundaries correctly #38

@gwtaylor

Description

@gwtaylor

Note that the output for the straightforward loop-based implementation is different from the correlation-based versions. In the static version of the notebook, the input is:

[[1 1 1 0 1 1 1 1 0 1]
 [0 1 0 1 0 1 0 0 1 1]
 [0 0 1 0 0 1 1 0 0 1]
 [0 0 0 0 0 1 1 0 0 1]
 [0 0 0 1 0 1 1 1 1 1]
 [0 0 1 0 1 0 1 0 0 0]
 [0 0 0 1 0 0 0 0 0 0]
 [0 1 0 0 0 1 0 1 1 0]
 [1 1 0 1 0 0 1 1 1 1]
 [0 0 1 0 0 0 0 0 0 0]]

The output for the loop-based implementation is:

[[0 0 0 0 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 0 0 0]
 [0 0 1 0 0 0 0 1 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 1 0 0 0 0 1 0]
 [0 0 1 0 1 0 1 0 1 0]
 [0 0 1 1 1 1 1 1 0 0]
 [0 1 0 0 1 0 0 0 0 0]
 [0 1 0 0 0 0 1 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]

The output for the cross correlation version is:

[[1 1 1 1 1 1 1 1 0 1]
 [1 0 0 1 0 0 0 0 0 1]
 [0 0 1 0 0 0 0 1 0 1]
 [0 0 0 0 0 0 0 0 0 1]
 [0 0 0 1 0 0 0 0 1 1]
 [0 0 1 0 1 0 1 0 1 0]
 [0 0 1 1 1 1 1 1 0 0]
 [1 1 0 0 1 0 0 0 0 1]
 [1 1 0 0 0 0 1 0 0 1]
 [0 1 1 0 0 0 0 1 1 0]]

Note that the difference is on the boundaries, and that's because the following line doesn't work for the boundaries:

neighbors = a[i-1:i+2, j-1:j+2]

A student in my class made this observation, and also supplied an alternative version that explicitly checks for boundaries. I have confirmed that this version produces the same output as the cross correlation version.

b = np.zeros_like(a)
rows, cols = a.shape
for i in range(0, rows):
    for j in range(0, cols):
        state = a[i, j]
        
        if i == 0 and j == 0:
            neighbors = a[i:i+2, j:j+2]
        elif j == 0:
            neighbors = a[i-1:i+2, j:j+2]
        elif i == 0:
            neighbors = a[i:i+2, j-1:j+2]
        else:
            neighbors = a[i-1:i+2, j-1:j+2]
            
        k = np.sum(neighbors) - state
        if state:
            if k==2 or k==3:
                b[i, j] = 1
        else:
            if k == 3:
                b[i, j] = 1

print(b)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions