【问题标题】:how do I find a coordinates given a number in Spiral pattern? [closed]如何在螺旋图案中找到给定数字的坐标? [关闭]
【发布时间】:2021-08-13 09:18:36
【问题描述】:

给定一个螺旋形的数字,其中数字以三角形的形式排列,我需要编写一个函数,该函数接受一个数字并返回该数字的坐标

           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,x 和 y 的结果是 (-2, 2)

我已经做过类似的任务,但是螺旋是方形的,程序接收坐标 (x, y) 作为输入并返回一个数字。简而言之,我在那里计算了正方形的大小和偏移量。

我会很高兴得到任何帮助

【问题讨论】:

    标签: python algorithm spiral


    【解决方案1】:

    TL;DR:底部的工作代码

    首先考虑每个三角形中有多少个数字:

    • 第一个在每条边包含 3 个数字
    • 第二个每条边包含 6 个数字
    • 第三个在每条边上包含 9 个数字

    这就是我们的模式。三角形i 包含9i 数字,在我们做任何其他事情之前,我们需要将我们的数字除以9 并找到结果的triangle root(并向下取整):

    一旦你找出了直角三角形,还有三件事要做:

    • 你需要找到起点

    这是微不足道的,因为三角形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
    

    【讨论】:

    • 这很好用,除了y 标志,我已经改变了return x, -y
    • 对,我用的是“编程”坐标,而不是数学坐标,所以根据你的需要翻转 :)
    【解决方案2】:

    没有代码,但我会从以下内容开始:

    1. 重新排列数字以了解三角形螺旋的结构
     0
     1  2
     3  4  5
     6  7  8  9
    10 11 12 13 14
    15 16 17 18 19 20
    21 22 23 24 25 26 27 
    ...
    

    请注意,如果我们取完整的线并将它们重新排列成螺旋形,我们将得到完整的三角形。

    1. 添加坐标(希望我理解正确。)
    0   0                      0, 0
    1   1  2                   1, 0    0, 1
    2   3  4  5               -1, 2   -1, 1  -1, 0
    
    3   6  7  8  9            -1,-1    0,-1   1,-1   2,-1
    4  10 11 12 13 14          3,-1    2, 0   1, 1   0, 2  -1, 3 
    5  15 16 17 18 19 20      -2, 4   -2, 3  -2, 2  -2, 1  -2, 0  -2,-1
    
    6  21 22 23 24 25 26 27   -2,-2    ...
    ...
    

    我还在前面加了一个行号r:三行在螺旋中形成一个完整的“转弯”。

    你可以看到行内的坐标模式,这当然取决于它如何被3除:

    • 可被 3 整除的行从 -r/3, -r/3 开始并递增 x
    • 余数为 1 的行从 2*(r-1)/3+1, -(r-1)/3 开始,递减 x 并递增 y
    • 余数为 2 的行从 -(r+1)/3, 2*(r+1)/3 开始并递减 y
    1. 找出我们实际上在哪一行

    r 行中的最后一个数字 n 是“n = {sum i for i from 0 to r+1} = (r+1)(r+2)/2”。我们为r 解决了这个问题并到达:

    r = -3/2 + sqrt(9/4 + 2n)
    

    只有正解是相关的。

    如果我们插入一个数字 n,比如 12,我们会得到 r = 3.6,这意味着我们在第 4 行的某个位置,请检查行号。

    1. 把东西放在一起
    • 计算当前行号。
    • 通过减去前一行的最后一个数字来计算行内的位置。 这通常是n_prev = r*(r+1)/2,在n=12 的示例中是n_prev = 4*5/2 = 10。 示例行内的位置为pos = 12-10 = 2
    • 计算当前行号除以 3 的余数。例如,我们有 4 = 3*1 + 1
    • 现在通过选择适当的公式来计算坐标。例如,我们有行4,余数1 和位置2,所以我们需要
    [2*(r-1)/3+1, -(r-1)/3] + pos*[-1, 1] = [2*3/3+1, -3/3] + [-2,2] = [1,1]
    

    再次,请检查您的初始螺旋三角形。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 2020-11-12
      • 2019-12-25
      相关资源
      最近更新 更多