Ruby,68岁
Lambda函数以复数为参数,返回复数。
->z{k=1
4.times{z*=?i.to_c
x,y=z.rect
y*y>=x*x&&y<-x&&(z+=k;k=0)}
z}
通过乘以将点旋转90度4次i
。因此,它会通过所有四个象限,并且将保持不变,除非我们在其中一个特定象限中对其进行了修改。总是在同一象限中对其进行修改的事实简化了修改。
如果我们将其更改z
为右侧象限,则最容易遵循。在这种情况下,我们需要将y坐标增加1(即i
加到)z
。
我们检查x.abs>=y.abs
通过比较的平方x
和y
。这告诉我们该点位于右侧或左侧象限,而不是顶部或底部。要检查它实际上是在右侧象限,我们进一步检查 x>y
(严格更大,因为我们要排除的情况下,x=y
属于“顶”象限。)如果这是真的,我们添加i
到z
。
由于打高尔夫球的原因,添加i
是不希望的。相反,当数字位于底部象限时,我们将对其进行修改,在这种情况下,我们必须将1加到x
坐标(将1加到)z
。在这种情况下,我们测试y*y>=x*x
以检查其是否位于顶部或底部象限。为了进一步确保它在底部象限中,我们需要检查y<-x
(严格排除右下角在的情况)y=-x
。
此检查的优点是,坐标0,0没有特殊情况。不幸的是,发现移动点可以将其移动到不同的象限,这意味着如果再次检查该象限,则必须抑制第二个运动,这可能会抵消其优势。
例子1
Input 95,-12
Rotate 90deg 12,95
Rotate 90deg -95,12
Rotate 90deg -12,-95
Rotate 90deg 95,-12
y.abs>=x.abs=TRUE, y<-x=TRUE, increase x 95,-11
The check and alteration of the coordinate is done AFTER the rotation.
Thus in this case it gets done in the 4th iteration of the loop, not the 1st.
If the code were rewritten to do the check and alteration BEFORE the rotation,
it would be done in the 1st iteration instead of the 4th.
例子2
Input -1,0
Rotate 90deg 0,-1
y.abs>=x.abs=TRUE, y<-x=TRUE, increase x 1,-1
Rotate 90deg 1,1
Rotate 90deg 1,-1
Rotate 90deg -1,-1
y.abs>=x.abs?=TRUE, y<-x=TRUE but DO NOT CHANGE x!
This is an unusual situation due to the fact that the first move caused the
point to advance by one quadrant. We do NOT want to move it again, for this
reason we need to set k to 0 the first time it is moved.
在测试程序中
f=->z{k=1 #amount to be added to coordinate
4.times{z*=?i.to_c #iterate 4 times, rotating point by 90deg till it reaches the original orientation
x,y=z.rect #separate out x and y for testing
y*y>=x*x&&y<-x&&(z+=k;k=0)} #if y.abs>=x.abs and y negative and not equal -x, move the point and zero k.
z} #return z
puts f[Complex(0, 0)] # (0, 0)
puts f[Complex(1, 0)] # (1, 1)
puts f[Complex(1, 1)] # (0, 1)
puts f[Complex(0, 1)] # (-1, 1)
puts f[Complex(-1, 1)] # (-1, 0)
puts
puts f[Complex(-1, 0)] # (-1, -1)
puts f[Complex(-1, -1)] # (0, -1)
puts f[Complex(0, -1)] # (1, -1)
puts f[Complex(1, -1)] # (1, 0)
puts f[Complex(95, -12)] # (95, -11)
puts f[Complex(127, 127)] # (126, 127)
puts
puts f[Complex(-2, 101)] # (-3, 101)
puts f[Complex(-65, 65)] # (-65, 64)
puts f[Complex(-127, 42)] # (-127, 41)
puts f[Complex(-9, -9)] # (-8, -9)
puts f[Complex(126, -127)] # (127, -127)
puts f[Complex(105, -105)] # (105, -104)
图表
下图显示了(蓝色)的区域x*x>=y*y
,(黄色)区域y<-x
和(绿色)它们的交点,这是正确的变换是将1加到的区域z
。