Iterar sobre matriz 2D em uma espiral circular em expansão
Given ann
porn
matrixM
, na linhai
e colunaj
, Gostaria de percorrer todos os valores vizinhos em uma espiral circula
O objetivo de fazer isso é testar alguma função,f
, que depende de M, para encontrar o raio longe de(i, j)
no qualf
retornaTrue
. Então,f
se parece com isso
def f(x, y):
"""do stuff with x and y, and return a bool"""
e seria chamado assim:
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
Ondecircle_around
é a função que retorna (um iterador para) os índices em uma espiral circular. Então, para cada ponto emM
, esse código calcularia e armazenaria o raio a partir daquele ponto em quef
retornaTrue
.
Se houver uma maneira mais eficiente de calcularR
, Eu também estaria aberto a iss
Obrigado a todos que enviaram respostas. Eu escrevi uma função curta para plotar a saída do seucircle_around
iteradores, para mostrar o que eles fazem. Se você atualizar sua resposta ou postar uma nova, poderá usar este código para validar sua solução.
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")
Aqui estão os resultados:plot(circle_around(0, 0), "F.J")
:
plot(circle_around(0, 0, 10), "WolframH")
:
Eu codifiquei a sugestão de magnésio da seguinte forma:
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")
:
Como você pode ver, nenhum dos resultados que satisfazem a interface que eu estou procurando produziu uma espiral circular que cobre todos os índices em torno de 0, 0. O FJ é o mais próximo, embora o WolframH atinja os pontos certos, apenas não em ordem espiral.