Iraterate sobre una matriz 2D en una espiral circular en expansión
Dan ann
porn
matrizM
, en la filai
y columnaj
, Me gustaría iterar sobre todos los valores vecinos en una espiral circular.
El punto de hacer esto es probar alguna función,f
, que depende de M, para encontrar el radio alejado de(i, j)
en el cualf
devolucionesTrue
. Entonces,f
Se ve como esto
def f(x, y):
"""do stuff with x and y, and return a bool"""
y se llamaría así:
R = numpy.zeros(M.shape, dtype=numpy.int)
# for (i, j) in M
for (radius, (cx, cy)) in circle_around(i, j):
if not f(M[i][j], M[cx][cy]):
R[cx][cy] = radius - 1
break
Dóndecircle_around
es la función que devuelve (un iterador a) índices en una espiral circular. Entonces, para cada punto enM
, este código calcularía y almacenaría el radio desde ese punto en el quef
devolucionesTrue
.
Si hay una manera más eficiente de computarR
, Yo también estaría abierto a eso.
Gracias a todos los que enviaron respuestas. He escrito una función corta para trazar la salida de tucircle_around
iteradores, para mostrar lo que hacen. Si actualiza su respuesta o publica una nueva, puede usar este código para validar su solución.
from matplotlib import pyplot as plt
def plot(g, name):
plt.axis([-10, 10, -10, 10])
ax = plt.gca()
ax.yaxis.grid(color='gray')
ax.xaxis.grid(color='gray')
X, Y = [], []
for i in xrange(100):
(r, (x, y)) = g.next()
X.append(x)
Y.append(y)
print "%d: radius %d" % (i, r)
plt.plot(X, Y, 'r-', linewidth=2.0)
plt.title(name)
plt.savefig(name + ".png")
Aquí están los resultados:plot(circle_around(0, 0), "F.J")
:
plot(circle_around(0, 0, 10), "WolframH")
:
He codificado la sugerencia de Magnesium de la siguiente manera:
def circle_around_magnesium(x, y):
import math
theta = 0
dtheta = math.pi / 32.0
a, b = (0, 1) # are there better params to use here?
spiral = lambda theta : a + b*theta
lastX, lastY = (x, y)
while True:
r = spiral(theta)
X = r * math.cos(theta)
Y = r * math.sin(theta)
if round(X) != lastX or round(Y) != lastY:
lastX, lastY = round(X), round(Y)
yield (r, (lastX, lastY))
theta += dtheta
plot(circle_around(0, 0, 10), "magnesium")
:
omo puede ver, ninguno de los resultados que satisfacen la interfaz que estoy buscando ha producido una espiral circular que cubre todos los índices alrededor de 0, 0. FJ es el más cercano, aunque WolframH alcanza los puntos correctos, solo no en orden espiral.