let x = 0
let y = 0
let d = 1
let m = 1
while true
while 2 * x * d < m
print(x, y)
x = x + d
while 2 * y * d < m
print(x, y)
y = y + d
d = -1 * d
m = m + 1
对于以各种编程语言编写的该问题,已经提出了许多建议的解决方案,但是它们似乎都源自相同的复杂方法。我将考虑计算螺旋的更一般的问题,可以使用归纳法将其简洁地表达出来。
基本情况:从(0,0)开始,向前移动1个正方形,向左转,向前移动1个正方形,向左转。归纳步骤:向前移动n + 1个正方形,向左转,向前移动n + 1个正方形,向左转。
表达此问题的数学优雅性强烈建议应该有一个简单的算法来计算解决方案。牢记抽象,我选择不以特定的编程语言实现算法,而是以伪代码实现。
首先,我将考虑一种算法,该算法使用4对while循环来计算螺旋的2次迭代。每对的结构相似,但其自身却各不相同。乍一看似乎很疯狂(某些循环仅执行一次),但我将逐步进行转换,直到我们得到4对相同的循环,因此可以用放置在另一个循环内的一对替换。这将为我们提供不使用任何条件即可计算n次迭代的一般解决方案。
let x = 0
let y = 0
//RIGHT, UP
while x < 1
print(x, y)
x = x + 1
while y < 1
print(x, y)
y = y + 1
//LEFT, LEFT, DOWN, DOWN
while x > -1
print(x, y)
x = x - 1
while y > -1
print(x, y)
y = y - 1
//RIGHT, RIGHT, RIGHT, UP, UP, UP
while x < 2
print(x, y)
x = x + 1
while y < 2
print(x, y)
y = y + 1
//LEFT, LEFT, LEFT, LEFT, DOWN, DOWN, DOWN, DOWN
while x > -2
print(x, y)
x = x - 1
while y > -2
print(x, y)
y = y - 1
我们将进行的第一个转换是引入一个新的变量d,该变量的方向为+1或-1。方向在每对循环之后切换。由于我们知道d在所有点上的值,因此我们可以将每个不等式的每一边乘以它,相应地调整不等式的方向,并将d与常数的任何乘积简化为另一个常数。这给我们留下了以下内容。
let x = 0
let y = 0
let d = 1
//RIGHT, UP
while x * d < 1
print(x, y)
x = x + d
while y * d < 1
print(x, y)
y = y + d
d = -1 * d
//LEFT, LEFT, DOWN, DOWN
while x * d < 1
print(x, y)
x = x + d
while y * d < 1
print(x, y)
y = y + d
d = -1 * d
//RIGHT, RIGHT, RIGHT, UP, UP, UP
while x * d < 2
print(x, y)
x = x + d
while y * d < 2
print(x, y)
y = y + d
d = -1 * d
//LEFT, LEFT, LEFT, LEFT, DOWN, DOWN, DOWN, DOWN
while x * d < 2
print(x, y)
x = x + d
while y * d < 2
print(x, y)
y = y + d
现在我们注意到x * d和RHS都是整数,因此我们可以从RHS中减去0到1之间的任何实数值,而不会影响不等式的结果。我们选择从每对while循环对的不等式中减去0.5,以建立更多的模式。
let x = 0
let y = 0
let d = 1
//RIGHT, UP
while x * d < 0.5
print(x, y)
x = x + d
while y * d < 0.5
print(x, y)
y = y + d
d = -1 * d
//LEFT, LEFT, DOWN, DOWN
while x * d < 1
print(x, y)
x = x + d
while y * d < 1
print(x, y)
y = y + d
d = -1 * d
//RIGHT, RIGHT, RIGHT, UP, UP, UP
while x * d < 1.5
print(x, y)
x = x + d
while y * d < 1.5
print(x, y)
y = y + d
d = -1 * d
//LEFT, LEFT, LEFT, LEFT, DOWN, DOWN, DOWN, DOWN
while x * d < 2
print(x, y)
x = x + d
while y * d < 2
print(x, y)
y = y + d
现在,我们可以为每个while循环对采取的步数引入另一个变量m。
let x = 0
let y = 0
let d = 1
let m = 0.5
//RIGHT, UP
while x * d < m
print(x, y)
x = x + d
while y * d < m
print(x, y)
y = y + d
d = -1 * d
m = m + 0.5
//LEFT, LEFT, DOWN, DOWN
while x * d < m
print(x, y)
x = x + d
while y * d < m
print(x, y)
y = y + d
d = -1 * d
m = m + 0.5
//RIGHT, RIGHT, RIGHT, UP, UP, UP
while x * d < m
print(x, y)
x = x + d
while y * d < m
print(x, y)
y = y + d
d = -1 * d
m = m + 0.5
//LEFT, LEFT, LEFT, LEFT, DOWN, DOWN, DOWN, DOWN
while x * d < m
print(x, y)
x = x + d
while y * d < m
print(x, y)
y = y + d
最后,我们看到,每对while循环的结构相同,可以简化为放置在另一个循环内部的单个循环。另外,为避免使用实数值,我将m的初始值乘以;m值增加;每个不等式的两边都加2。
这导致该答案开头显示的解决方案。