ルビー、64バイト
まず、私の提出。引数を持つラムダ関数distance 1, angle 1, distance 2, angle2
。
->r,a,s,b{([d=(b-a).abs,?i.to_c.arg*4-d,2].min-2)*[r,s].min+s+r}
次に、66バイト(割り当てを除くf=
)の2つの異なるソリューションと、64バイトでの実際の送信を示します。
Solution 1:Using include Math, 66 bytes excluding f=
include Math;f=->r,a,s,b{[acos(cos(b-a)),2].min*[r,s].min+(s-r).abs}
Solution 2:Using complex number to define PI instead, 66 bytes excluding f=
f=->r,a,s,b{[d=(b-a).abs,?i.to_c.arg*4-d,2].min*[r,s].min+(s-r).abs}
SUBMISSION AGAIN, 64 bytes excluding f=
f=->r,a,s,b{([d=(b-a).abs,?i.to_c.arg*4-d,2].min-2)*[r,s].min+s+r}
送信はソリューション2に基づいていますが、identity (s-r).abs
= s+r-[s,r].min*2
を使用してコードを2バイト短縮-2
します。したがって、括弧内になります。
もう1つの注目すべき機能は、?i.to_c.arg*4
を使用しないexpression = 2 * PI include Math
です。より低い精度が許容される場合、これはリテラルに置き換えることができます。
ソリューション2がテストプログラムでコメントされました
f=->r,a,s,b{ #r,s are distances, a,b are angles for points 1 and 2 respectively.
[d=(b-a).abs, #From nearer point we can take arc of length d radians perhaps crossing zero angle to the ray of the further point
?i.to_c.arg*4-d, #or go the other way round which may be shorter (?i.to_c.arg*4 == 2*PI, subtract d from this.)
2].min* #or go through the centre if the angle exceeds 2 radians.
[r,s].min+ #Multiply the radians by the distance of the nearer point from the origin to get the distance travelled.
(s-r).abs #Now add the distance to move along the ray out to the further point.
}
#test cases per question (given as complex numbers, converted to arrays of [distance,angle]+[distance,angle] (+ concatenates.)
#the "splat" operator * converts the array to 4 separate arguments for the function.
p f[*("1+i".to_c.polar + "1-i".to_c.polar)]
p f[*("0".to_c.polar + "1+i".to_c.polar)]
p f[*("1".to_c.polar + "-0.4161+0.90929i".to_c.polar)]
p f[*("1+i".to_c.polar + "1".to_c.polar)]
p f[*("1+2i".to_c.polar + "3+4i".to_c.polar)]
出力
2.221441469079183
1.4142135623730951
1.9999342590038496
1.1996117257705434
3.1660966740274357