Your code is correct if you want to count the elements adjacent to a given one in a finite matrix. The problem is that your matrix is theoretically infinite.
I do not know if you're limited to doing it using cycles for
or anything else. Otherwise, it is very simple if you use slicing of lists / strings and the module operation or rest of the whole division:
-
We have for example the case of the matrix:
#.
.#
And they ask us to count the cells adjacent to the element (0,0)
-
What we need is to reconstruct the 3x3 matrix that would result from centering the one we have (which in reality is infinite) in the element that they indicate to us. In our case it would be to obtain the following matrix:
#.#
.#.
#.#
-
To do this we must consider a couple of things:
-
Phyton allows the use of negative indexes:
>>> s='hola'
>>> print(s[-1])
>>> a
-
If we want to create a circular or cyclical list we can make use of modular arithmetic using the module operator ( %
) or rest of the whole division:
def elemento(iterable, indice):
return(iterable[indice%len(iterable)])
s = 'Hola-'
for i in range(0,20):
print(elemento(s, i))
We can see how we can pass an index as large as we want and thanks to modular arithmetic we can travel with infinite indexes a finite list. With these two ideas we can iterate infinitely on any iterable in both directions.
- In reality we only need the 8 peripheral elements of the previous matrix and count those that are
'#'
. For this we can use the method count
.
With the above concepts the code is simply in:
def cant_adyacentes(life, f, c):
fs = life[f-1]
fi = life[(f+1)%len(life)]
i=(c+1)%len(life[0])
return (fs[c-1], fs[c], fs[i], life[f][c-1], life[f][i], fi[c-1], fi[c], fi[i]).count('#')
def pruebas_cant_adyacentes():
assert cant_adyacentes((['.']), 0, 0) == 0
assert cant_adyacentes((['..', '..']), 0, 0) == 0
assert cant_adyacentes((['..', '..']), 0, 1) == 0
assert cant_adyacentes((['##', '..']), 0, 0) == 2
assert cant_adyacentes((['##', '..']), 0, 1) == 2
assert cant_adyacentes((['#.', '.#']), 0, 0) == 4
assert cant_adyacentes((['##', '##']), 0, 0) == 8
assert cant_adyacentes((['.#.', '#.#', '.#.']), 1, 1) == 4
assert cant_adyacentes((['.#.', '..#', '.#.']), 1, 1) == 3
pruebas_cant_adyacentes()
fs
is the row that is above the one that contains the element on which we calculate the adjacent cells.
fi
is the bottom row.
i
is the index using modular arithmetic that we must use to obtain the elements of the column located to the right of the one that contains our target element.
The elements on the left or the top row do not give problems because Python itself understands the negative indices and at most we will need the -1 index. The elements on the right or rows below if they give problems because if the index is greater than the length of the iterable minus one will generate an error. In this last case we make use of modular arithmetic.