找到矩形平铺螺旋的第n个元素?

时间:2012-04-10 18:57:05

标签: algorithm spiral

获取矩形平铺螺旋的第n个元素的算法是什么?

以下是n

[ 20  ][ 21  ][ 22  ][ 23  ][ 24  ]
[ 19  ][  6  ][  7  ][  8  ][  9  ]
[ 18  ][  5  ][  0  ][  1  ][ 10  ]
[ 17  ][  4  ][  3  ][  2  ][ 11  ]
[ 16  ][ 15  ][ 14  ][ 13  ][ 12  ]

以下是n的对应坐标:

[-2,2 ][-1,2 ][ 0,2 ][ 1,2 ][ 2,2 ]
[-2,1 ][-1,1 ][ 0,1 ][ 1,1 ][ 2,1 ]
[-2,0 ][-1,0 ][ 0,0 ][ 1,0 ][ 2,0 ]
[-2,-1][-1,-1][ 0,-1][ 1,-1][ 2,-1]
[-2,-2][-1,-2][ 0,-2][ 1,-2][ 2,-2]

如果给定n,如何计算坐标?

6 个答案:

答案 0 :(得分:13)

这是一个简短而甜蜜的答案,只使用伪代码中的简单数学。没有条件,没有迭代。给定tileNum作为图块编号:

intRoot=int(sqrt(tileNum));

x=(round(intRoot/2)*(-1^(intRoot+1)))+((-1^(intRoot+1))*(((intRoot*(intRoot+1))-tileNum)-abs((intRoot*(intRoot+1))-tileNum))/2);

y=(round(intRoot/2)*(-1^intRoot))+((-1^(intRoot+1))*(((intRoot*(intRoot+1))-tileNum)+abs((intRoot*(intRoot+1))-tileNum))/2);

Here's a fiddle看到它的实际效果。

答案 1 :(得分:4)

这是JavaScript中的代码。它计算中间(0,0)

中从数字1开始的2D矩阵的位置
13  12  11  10  25
14   3   2   9  24
15   4   1   8  23
16   5   6   7  22
17  18  19  20  21

/**
 * Finds coordinates (position) of the number
 * 
 * @param {Number} n - number to find position/coordinates for
 * @return {Number[]} - x and y coordinates of the number
 */
function position(n) {
    const k = Math.ceil((Math.sqrt(n) - 1) / 2);
    let t = 2 * k + 1;
    let m = Math.pow(t, 2);

    t -= 1;

    if (n >= m - t) {
        return [k - (m - n), -k];
    }

    m -= t;

    if (n >= m - t) {
        return [-k, -k + (m - n)];
    }

    m -= t;

    if (n >= m - t) {
        return [-k + (m - n), k];
    }

    return [k, k - (m - n - t)];
}

答案 2 :(得分:2)

首先,找出你想要的元素所在的环(提示:直到你到达外环,你的螺旋由嵌套的方块组成),然后是它所在的那一侧(4),然后你'我只是留在那边的位置。

答案 3 :(得分:1)

已存在类似问题...请参阅我的non-looping version。您可能需要交换和/或否定X / Y坐标,并根据您想要的方向和原点将100更改为0

还有更多规范looping versions

答案 4 :(得分:1)

没有人回答,有一个解决方案:

def square_spiral(total_steps):
    position = (0,0)
    direction = (1,0)
    turn_steps = [floor(((x+2)**2)/4) for x in range(n+2)]
    for step in range(total_steps):
        if (step in turn_steps):
            direction = (-direction[1],direction[0])
        position = tuple(a+b for a,b in zip(position,direction))
    return position

这模拟了通过所需路径的步行。从位置(0,0)开始,向右走1步,向下走1步,向左走3步,向上走3步,依此类推螺旋。要对此进行编码,请注意我们正在改变数字1,2,4,6,9,12,16,20等步骤的方向。 https://oeis.org/显示这是四分之一平方的整数序列。所以我们需要的是一个循环,每个迭代模拟一个步骤,将位置添加到位置,当步数是序列的一部分时将其旋转90º。

答案 5 :(得分:1)

这是我在javascript中的解决方案,使用反向和8和边数编号

复杂性:O(1)没有迭代循环

function spiral(n) {
    // given n an index in the squared spiral
    // p the sum of point in inner square
    // a the position on the current square
    // n = p + a

    var r = Math.floor((Math.sqrt(n + 1) - 1) / 2) + 1;

    // compute radius : inverse arithmetic sum of 8+16+24+...=
    var p = (8 * r * (r - 1)) / 2;
    // compute total point on radius -1 : arithmetic sum of 8+16+24+...

    en = r * 2;
    // points by edge

    var a = (1 + n - p) % (r * 8);
    // compute de position and shift it so the first is (-r,-r) but (-r+1,-r)
    // so square can connect

    var pos = [0, 0];
    switch (Math.floor(a / (r * 2))) {
        // find the face : 0 top, 1 right, 2, bottom, 3 left
        case 0:
            {
                pos[0] = a - r;
                pos[1] = -r;
            }
            break;
        case 1:
            {
                pos[0] = r;
                pos[1] = (a % en) - r;

            }
            break;
        case 2:
            {
                pos[0] = r - (a %en);
                pos[1] = r;
            }
            break;
        case 3:
            {
                pos[0] = -r;
                pos[1] = r - (a % en);
            }
            break;
    }
    console.log("n : ", n, " r : ", r, " p : ", p, " a : ", a, "  -->  ", pos);
    return pos;
}

演示:Fiddle