Hồng ngọc, 68
Hàm Lambda lấy số phức làm đối số, trả về số phức.
->z{k=1
4.times{z*=?i.to_c
x,y=z.rect
y*y>=x*x&&y<-x&&(z+=k;k=0)}
z}
Chúng tôi xoay điểm qua 90 độ 4 lần bằng cách nhân với i
. Do đó, nó đi qua tất cả 4 góc phần tư và sẽ được trả lại không thay đổi - ngoại trừ thực tế chúng ta sửa đổi nó khi nó nằm trong một trong số chúng cụ thể. Thực tế nó luôn được sửa đổi trong cùng một góc phần tư đơn giản hóa việc sửa đổi.
Dễ dàng nhất để làm theo nếu chúng ta thay đổi nó z
khi nó nằm trong góc phần tư bên phải. trong trường hợp này, chúng ta cần tăng tọa độ y lên 1 (tức là thêm i
vào z
.)
Chúng tôi kiểm tra x.abs>=y.abs
bằng cách so sánh các hình vuông của x
và y
. Điều này cho chúng ta biết điểm nằm ở góc phần tư bên phải hoặc bên trái, không phải trên cùng hoặc dưới cùng. Để kiểm tra xem thực tế là trong góc phần tư tay phải, chúng tôi kiểm tra thêm x>y
(hoàn toàn lớn hơn vì chúng tôi muốn loại trừ trường hợp x=y
thuộc góc phần tư "trên cùng".) Đây là điều đúng mà chúng tôi thêm i
vào z
.
Đối với lý do chơi golf, thêm i
là không mong muốn. Thay vào đó, chúng tôi sửa đổi số khi nó nằm trong góc phần tư dưới cùng, trong trường hợp đó chúng ta phải thêm 1 vào x
tọa độ (thêm 1 vào z
.) Trong trường hợp này, chúng tôi kiểm y*y>=x*x
tra xem nó có nằm trong góc phần tư trên hay dưới không. Để đảm bảo hơn nữa nó nằm trong góc phần tư phía dưới, chúng ta cần kiểm tra y<-x
(không bao gồm nghiêm ngặt trường hợp góc dưới cùng bên phải y=-x
.)
Một lợi thế của kiểm tra này là không có trường hợp đặc biệt nào cho tọa độ 0,0. Thật không may, người ta đã phát hiện ra rằng việc di chuyển điểm có thể chuyển nó sang một góc phần tư khác và điều này có nghĩa là một chuyển động thứ hai phải bị triệt tiêu nếu góc phần tư đó được kiểm tra lại, điều này có thể phủ nhận lợi thế.
ví dụ 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.
Ví dụ 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.
Trong chương trình thử nghiệm
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)
Sơ đồ
Hình ảnh sau đây cho thấy (màu xanh) khu vực trong đó x*x>=y*y
, (màu vàng) khu vực nơi y<-x
và (màu xanh lá cây) giao điểm của những khu vực này, là khu vực nơi chuyển đổi chính xác là thêm 1 vào z
.