루비, 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
. 따라서 4 사분면을 모두 통과하며 특정 사분면에있을 때 수정한다는 점을 제외하고 변경되지 않은 상태로 반환됩니다. 항상 동일한 사분면에서 수정되므로 수정이 간단 해집니다.
z
오른쪽 사분면에있을 때 변경하면 따르는 것이 가장 쉬운 방법 입니다. 이 경우 우리는 y는 1 좌표 증가시켜야합니다 (즉, 추가 i
로 z
.)
우리는 확인 x.abs>=y.abs
의 제곱을 비교 x
하고 y
. 이것은 포인트가 상단 또는 하단이 아니라 오른쪽 또는 왼쪽 사분면에 있음을 나타냅니다. 실제로는 오른쪽 사분면에서이를 확인하기 위해 추가로 확인합니다 x>y
( x=y
"상단"사분면에 속하는 경우를 제외하기 위해 엄청나게 더 큼 ).이 경우에 추가 i
합니다 z
.
골프를 이유로 추가 i
하는 것은 바람직하지 않습니다. 대신, 우리는 그것이 아래 사분면에있을 때 숫자를 수정합니다 .이 경우 x
좌표 에 1을 더해야 합니다 (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
입니다.