ルビー、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つの象限すべてを通過し、特定の1つにある場合に変更するという事実を除き、変更されずに返されます。同じ象限で常に変更されるという事実は、変更を単純化します。
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に特別なケースがないことです。残念ながら、ポイントを移動すると別の象限に移動する可能性があり、これはその象限を再度チェックした場合に2番目の移動を抑制する必要があることを意味し、おそらく利点を無効にします。
例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
です。