Polar Grafik Grafiğinde Seyahat Eden İki Nokta Arası Mesafe


23

Kısa Sorun Açıklaması

Yalnızca orijinden çıkan ışınlar ve orijine merkezlenmiş daireler üzerinde seyahat eden iki nokta arasındaki minimum mesafeyi bulmak için bir program yazın.

Öncül açıklaması

Şimdi bir uçakta olduğumuzu ve bu uçakta sadece özel yollarla seyahat etmemize izin verildiğini düşünelim. Menşe kaynaklı herhangi bir ışın üzerinde seyahat etmemize izin verilir.

Seyahat edebileceğimiz ışınlar

Ayrıca bir dairede merkezlenmiş herhangi bir dairede seyahat edebiliriz

Seyahat edebileceğimiz çevreler

Şimdi hedefimiz bu uçaktaki bir noktadan diğerine seyahat etmektir. Ancak, sadece basit bir Öklid yolunda seyahat edemeyiz, ancak eğer noktalar merkezden yayılan bir ışın üzerine düşerse bunu yapabiliriz.

görüntü tanımını buraya girin

Bu konuda seyahat edebiliriz çünkü ışınlarımızdan birine düşüyor.

görüntü tanımını buraya girin

Ayrıca orijin merkezindeki daireleri de gezebiliriz.

görüntü tanımını buraya girin

Örnekler

Şimdi burada zorluk:

En kısa yoldan bir noktadan diğerine geçmeliyiz; genellikle bu, daireler ve ışınlar üzerinde seyahat etmenin bir kombinasyonudur.

görüntü tanımını buraya girin

Ancak bu, iki ışınla da seyahat ediyor olabilir.

görüntü tanımını buraya girin

Bazen asgari mesafeye giden iki yol vardır.

görüntü tanımını buraya girin

Sorun

Buradaki zorluğunuz, bu kurallara uymamız halinde iki nokta verildiğinde bize aralarındaki minimum mesafeyi verecek bir program yazmaktır. Girişler dikdörtgen veya kutup şeklinde verilebilir ve çıktı arasındaki mesafenin bir sayı olması gerekir.

Test Kılıfları

(dikdörtgen girişli)

(1,1) (1,-1) -> ~ 2.22144
(0,0) (1, 1) -> ~ 1.41421
(1,0) (-0.4161 , 0.90929) -> ~ 2
(1,1) (1, 0) -> ~ 1.19961
(1,2) (3, 4) -> ~ 3.16609

Örnek test durumları dikdörtgen mi yoksa kutuplu mu? Ayrıca:
bewteen

Dikdörtgen formdalar, şunu açıklığa kavuşturmalıyım
Ando Bando

Son örnek doğru mu? ~
3.166

6
@Peter Taylor Çünkü onlar gerçekten aynı yol değil. Benzer bir şekilde, xy düzlemi üzerinde 0,0 ile 1,1 arasındaki bir yolla, x ve y yönlerinde değişen küçük adımlarla, adım uzunluğu sıfıra yöneldikçe doğrudan çapraz bir yolla aynı görünür. Adım yol daima uzunluğu 2. sahipken, Ama diyagonal yol uzunluğu sqrt (2) sahiptir
Penguino

1
Görüntüler çok büyük olmasa meydan okumanın daha iyi görüneceğini düşünüyorum. Şu anda metni takip etmeyi zorlaştırıyorlar
Luis Mendo

Yanıtlar:


5

Haskell, 49 48 bayt

(a!q)c r=min(q+r)$abs(q-r)+acos(cos$a-c)*min q r

Kullanımı:

> let rect2polar (x,y)=(atan2 y x, sqrt(x^2+y^2))
> let test c1 c2=let [(a1,r1),(a2,r2)]=rect2polar<$>[c1,c2] in (a1!r1)a2 r2
> test (1,0) (-0.4161, 0.90929)
1.9999342590038496

Bir bayt tasarrufu için @ Zgarb sayesinde


Bir bayt (a!q)c ryerine tanımlayarak kaydedebilirsiniz d a q c r.
Zgarb

4

JavaScript (ES6), 65 bayt

with(Math)(r,t,s,u,v=acos(cos(t-u)))=>v<2?abs(r-s)+v*min(r,s):r+s

Kutupsal koordinatları alır. Bir açıyı 0 ile π arasında azaltmak için @Angs hilesini kullanır. Dikdörtgen koordinatlar için, bunun gibi bir şey işe yarar:

with(Math)g=(r,t,s,u,v=acos(cos(t-u)))=>v<2?abs(r-s)+v*min(r,s):r+s
with(Math)f=(x,y,v,w)=>g(hypot(y,x),atan2(y,x),hypot(w,v),atan2(y,v))

3

MATL , 22 bayt

|ttsGZ}/X/bX<*|bd|+hX<

Giriş iki karmaşık sayı dizisidir.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

açıklama

|       % Implicitly input array and take absolute value of its entries
tt      % Duplicate twice
s       % Sum. This is the length of the path that follows the two radii
GZ}     % Push input again and split into the two numbers
/X/     % Divide and compute angle. This gives the difference of the angles
        % of the two points, between -pi and pi
bX<     % Bubble up a copy of the array of radii and compute minimum
*|      % Multiply and take absolute value. This is the arc part of the
        % path that follows one arc and the difference of radii
bd|     % Bubble up a copy of the array of radii and compute absolute
        % difference. This is the other part of the second path
+       % Add. This gives the length of second path
hX<     % Concatenate and take minimum to produce the smallest length.
        % Implicitly display

2

Ruby, 64 bayt

İlk önce benim gönderim. Bağımsız değişkenlerle Lambda işlevi 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}

Şimdi burada 66 baytlık iki farklı çözüm (atanma hariç f=) ve ardından 64 baytta tekrar gönderim yapıldı.

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}

Gönderme, 2. çözüme dayanır, ancak kimliği (s-r).abs= s+r-[s,r].min*2kodu kullanarak 2 bayt kısaltır, dolayısıyla -2parantezlerin içinde.

Dikkate değer bir diğer özellik, ?i.to_c.arg*4kullanmadan = 2 * PI ifadesidir include Math. Daha düşük hassasiyet kabul edilebilirse, bunun değişmez bir değeri olabilir.

2. Çözüm, test programında yorum yaptı

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)]

Çıktı

2.221441469079183
1.4142135623730951
1.9999342590038496
1.1996117257705434
3.1660966740274357

2

Mathematica 66 Bayt

Bu dikdörtgen koordinatları alır ve tam bir sembolik çözüm üretebilir

Min[If[(m=Min[{p,q}=Norm/@#])>0,m*VectorAngle@@#,0]+Abs[p-q],p+q]&

Kullanımı:

%/@{
{{1,1},{1,-1}},
{{0,0},{1,1}},
{{1,0},{-.4161,.90929}},
{{1,1},{1,0}},
{{1,2},{3,4}}
}

verim: sembolik sonuç

% @ Verim:

{2.221441469, 1.414213562, 1.999934259, 1.199611726, 3.166096674)


1
Şık! sembolik rotaya giderseniz, {1,0} {-. 4161, .90929} test senaryosunu {1,0} {cos (2), sin (2)} ile değiştirebilirsiniz
Ando Bando

1

Python 2, 164 126 125 132 bayt:

def A(a,b,c,d,p=3.1415926535):z=abs(a-c);M=lambda f:2*p*f*abs(b-d)/360.0;print min((a==c)*min(a+c,M(a))+(b==d)*z or'',M(a)+z,M(c)+z)

Şu anda bu daha çok golf arıyorum. Kutupsal koordinatları kabul eder. Biçiminde çağrılmalıdır A(r1,θ1,r2,θ2). 12Önemli rakamlara kadar hassas bir kayan nokta değeri verir .

Çevrimiçi Deneyin! (Ideone)

Aşağıdakileri içeren en fazla 3 değer dizisinden asgari değeri STDOUT hesaplayan ve çıkaran basit, basit bir uygulama:

  1. iki uzunluğun (toplamı ya da üzerinden minimum değer r1+r2) ya da iki noktayı birleştiren bir yay uzunluğu IFF r1==r2 ;
  2. fark, iki mesafe arasında ( abs(r1-r2)) ancak ve ancak θ1==θ2 (yani, iki nokta kolineerdir);
  3. önceki 2 öğeden hiçbiri eklenmezse, ''Python'da boş bir dize ( ) göründüğü gibi bir dize herhangi bir tamsayıdan büyüktür ;
  4. ve bir daire boyunca gidilen mesafelerden verilen iki nihai değer ve iki nokta arasında bir ışın ve bunun tersi.

Neden olmasın math.pi?
user202729

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.