Distanza tra due punti viaggiando su un grafico polare


23

Breve spiegazione del problema

Scrivi un programma per trovare la distanza minima tra due punti che viaggiano solo su raggi che provengono dall'origine e cerchi centrati sull'origine.

Spiegazione dei locali

Ora immaginiamo di essere su un piano e su questo piano ci è permesso viaggiare solo in modi speciali. Ci è permesso viaggiare su qualsiasi raggio proveniente dall'origine.

Raggi su cui possiamo viaggiare

Possiamo anche viaggiare su qualsiasi cerchio centrato su un cerchio

Cerchi su cui possiamo viaggiare

Ora il nostro obiettivo è viaggiare da un punto su questo piano all'altro. Tuttavia, non possiamo limitarci a percorrere un semplice percorso euclideo, possiamo farlo solo se i punti cadono su un raggio che emana dal centro.

inserisci qui la descrizione dell'immagine

Possiamo viaggiare su questo perché cade su uno dei nostri raggi.

inserisci qui la descrizione dell'immagine

Possiamo anche viaggiare su cerchi centrati sull'origine.

inserisci qui la descrizione dell'immagine

Esempi

Ora ecco la sfida:

Dobbiamo andare da un punto all'altro nel percorso più breve; spesso questa è una combinazione di viaggiare su cerchi e raggi.

inserisci qui la descrizione dell'immagine

Questo, tuttavia, potrebbe anche viaggiare su due raggi.

inserisci qui la descrizione dell'immagine

A volte esistono due percorsi che percorrono la distanza minima.

inserisci qui la descrizione dell'immagine

Problema

La tua sfida è quella di scrivere un programma che quando ci vengono dati due punti ci darà la distanza minima tra loro se seguiamo queste regole. Gli input possono essere dati in forme rettangolari o polari e l'output dovrebbe essere un numero, la distanza tra.

Casi test

(con ingresso rettangolare)

(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

Gli esempi di test sono in forme rettangolari o polari? Inoltre: bewteen
Angs

Sono in forma rettangolare, dovrei chiarire che
Ando Bando,

L'ultimo esempio è corretto? Ricevo ~ 3.166
Angs

6
@Peter Taylor Perché non sono proprio lo stesso percorso. In modo simile, un percorso da 0,0 a 1,1 sul piano xy attraverso piccoli passi che si alternano nelle direzioni xey appare identico a un percorso diagonale diretto poiché la lunghezza del passo tende a zero. Ma il percorso diagonale ha lunghezza sqrt (2) mentre il percorso del passo avrà sempre lunghezza 2.
Penguino,

1
Penso che la sfida sarebbe migliore se le immagini non fossero così grandi. Attualmente rendono difficile seguire il testo
Luis Mendo,

Risposte:


5

Haskell, 49 48 byte

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

Uso:

> 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

Grazie a @Zgarb per aver salvato un byte


È possibile salvare un byte definendo (a!q)c rinvece di d a q c r.
Zgarb,

4

JavaScript (ES6), 65 byte

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

Accetta coordinate polari. Usa il trucco di @Angs per ridurre un angolo tra 0 e π. Per coordinate rettangolari, qualcosa del genere funziona:

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 byte

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

L'input è un array di due numeri complessi.

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

|       % 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

Rubino, 64 byte

Innanzitutto, la mia presentazione. Funzione lambda con argomenti 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}

Ora ecco due diverse soluzioni di 66 byte (escluso il compito f=) seguite dalla mia attuale presentazione di nuovo a 64 byte.

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}

L'invio si basa sulla soluzione 2, ma utilizza l'identità (s-r).abs= s+r-[s,r].min*2per abbreviare il codice di 2 byte, quindi -2all'interno delle parentesi.

L'altra caratteristica notevole è l'espressione ?i.to_c.arg*4= 2 * PI senza usare include Math. Se una precisione inferiore è accettabile, questa può essere sostituita da una lettera.

Soluzione 2 commentata nel programma di test

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

Produzione

2.221441469079183
1.4142135623730951
1.9999342590038496
1.1996117257705434
3.1660966740274357

2

Mathematica 66 byte

Questo richiede coordinate rettangolari e può generare una soluzione simbolica esatta

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

Uso:

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

rendimenti: risultato simbolico

N @% rese:

{2.221441469, 1.414213562, 1.999934259, 1.199611726, 3.166096674}


1
Nifty! se stai seguendo il percorso simbolico puoi sostituire il caso di test {1,0} {-. 4161, .90929} con {1,0} {cos (2), sin (2)}
Ando Bando

1

Python 2, 164 126 125 132 byte:

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)

Al momento, però, sto studiando di più sul golf. Accetta coordinate polari. Dovrebbe essere chiamato nel formato A(r1,θ1,r2,θ2). Emette un valore in virgola mobile accurato fino a 12cifre significative.

Provalo online! (Ideone)

Un'implementazione semplice e diretta che calcola e restituisce a STDOUT il valore minimo da un array di al massimo 3 valori contenenti:

  1. il valore minimo tra la somma delle due lunghezze ( r1+r2) o la lunghezza dell'arco che collega i due punti iff r1==r2 ;
  2. la differenza tra le due distanze ( abs(r1-r2)) iff θ1==θ2 (ovvero i due punti sono collineari);
  3. se nessuno dei 2 elementi precedenti viene aggiunto, allora una stringa vuota ( '') come apparentemente in Python una stringa è maggiore di qualsiasi numero intero;
  4. e 2 valori finali dati dalle distanze percorse lungo un cerchio e un raggio e viceversa tra i due punti.

Perché no math.pi?
user202729

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.