Rubin, 68
Die Lambda-Funktion nimmt eine komplexe Zahl als Argument und gibt eine komplexe Zahl zurück.
->z{k=1
4.times{z*=?i.to_c
x,y=z.rect
y*y>=x*x&&y<-x&&(z+=k;k=0)}
z}
Wir drehen den Punkt viermal um 90 Grad, indem wir mit multiplizieren i
. Es durchläuft daher alle 4 Quadranten und wird unverändert zurückgegeben - mit Ausnahme der Tatsache, dass wir es ändern, wenn es sich in einem bestimmten von ihnen befindet. Die Tatsache, dass es immer im selben Quadranten geändert wird, vereinfacht die Änderung.
Es ist am einfachsten zu folgen, wenn wir es ändern, z
wenn es sich im rechten Quadranten befindet. in diesem Fall müssen wir die y-Koordinate um 1 erhöhen (dh i
zu z
. hinzufügen )
Wir überprüfen dies x.abs>=y.abs
durch Vergleichen der Quadrate von x
und y
. Dies sagt uns, dass der Punkt im rechten oder linken Quadranten liegt, nicht oben oder unten. Um zu überprüfen , es in der Tat im rechten Quadranten prüfen wir weiterhin , dass x>y
( die streng größer , weil wir den Fall ausschließen möchten , x=y
die an der „Spitze“ Quadranten gehört.) Wo dies der Fall ist fügen wir i
zu z
.
Aus Golfgründen ist das Hinzufügen i
nicht wünschenswert. Stattdessen ändern wir die Zahl, wenn sie sich im unteren Quadranten befindet . In diesem Fall müssen wir 1 zur x
Koordinate hinzufügen (1 zu hinzufügen z
). In diesem Fall testen wir, y*y>=x*x
ob sie sich im oberen oder unteren Quadranten befindet. Um weiterhin sicherzustellen, dass es sich im unteren Quadranten befindet, müssen wir dies überprüfen y<-x
(wobei der Fall der unteren rechten Ecke strikt ausgeschlossen ist y=-x
).
Ein Vorteil dieser Prüfung ist, dass es keinen Sonderfall für die Koordinate 0,0 gibt. Leider wurde festgestellt, dass das Verschieben des Punktes zu einem anderen Quadranten führen kann und dies bedeutet, dass eine zweite Bewegung unterdrückt werden muss, wenn dieser Quadrant erneut überprüft wird, was wahrscheinlich den Vorteil zunichte macht.
Beispiel 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.
Beispiel 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.
Im Testprogramm
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)
Diagramm
Das folgende Bild zeigt (blau) den Bereich x*x>=y*y
, in dem (gelb) der Bereich y<-x
und (grün) der Schnittpunkt von diesen ist, der Bereich, in dem die korrekte Transformation die Addition von 1 zu ist z
.