如何在螺旋图案中找到给定数字的坐标?
给定一个数字螺旋,其中数字以三角形的形式排列,我需要编写一个函数,该函数接受一个数字并返回该数字的坐标
15
16 14
17 3 13
18 4 2 12
19 5 0> 1 11
20 6 7 8 9 10
21 22 23 24 25 26 27 28
例如 17 结果是 (-2, 2) 在 x 和 y
我已经做了一个类似的任务,但螺旋是方形的,程序接收坐标 (x, y) 作为输入并返回一个数字。简而言之,我计算了正方形的大小和偏移量。
我会很高兴得到任何帮助
回答
TL;DR:底部的工作代码
首先考虑每个三角形中有多少个数字:
- 第一个在每条边中包含 3 个数字
- 第二个在每条边上包含 6 个数字
- 第三个在每条边中包含 9 个数字
所以这就是我们的模式。三角形i包含9i数字,在我们做任何其他事情之前,我们需要将数字除以9并找到结果的三角形根(并将其向下取整):
一旦你弄清楚了直角三角形,还有三件事要做:
- 你需要找到起点
这是微不足道的,因为三角形的“最后一点”i将始终是(2i, i)。
- 你需要找到正确的边缘
您已经知道您的三角形有i-long 边,因此通过将余数(来自原始divmod和生根)的总和除以 3,您可以找到正确的边。
- 你需要在这条边上找到正确的点
这一点很简单 - 你有 3 种类型的边缘,水平、垂直和对角线。根据您必须将“最终残值”应用于“边缘原点”的类型:
(-r, -r)对于对角线(0, r)对于垂直(r, 0)对于水平
相对于前一个三角形的最大点到达右边缘,您只需应用这些换位的累积总和:
(-r, -r)对于对角线(-i, -i+r)对于垂直(-i+r, 0)对于水平
把这一切放在一起
def triangle_root(x):
return int((8 * x + 1) ** 0.5 - 1) // 2
def spiral(v):
# Identify the current triangle
i = min(v, triangle_root(max(0, (v - 1) / 9)) + 1)
# Compute the coordinates for the max value of this triangle
xi, yi = 2 * i, i
# Compute the point index in the current triangle
# In other words, subtract the previous triangle max
r = v - 9 * (i - 1) * i // 2
# Compute the edge length for the current triangle
length = 3 * max(1, i)
# Compute the current edge and the location in that edge
edge, r = divmod(r, length)
# Apply the relevant transform depending on the edge
if edge == 1: # vertical
dx, dy = -length, r - length
elif edge == 2: # horizontal
dx, dy = r - length, 0
else: # diagonal
dx, dy = -r, -r
return xi + dx, yi + dy