获取矩形平铺螺旋的第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
,如何计算坐标?
答案 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