Distancia entre dos puntos que viajan en un gráfico de gráfico polar

23

Breve explicación del problema

Escriba un programa para encontrar la distancia mínima entre dos puntos que viajan solo en rayos que emanan del origen y círculos centrados en el origen.

Explicación de la premisa

Ahora imaginemos que estamos en un avión, y en este avión solo se nos permite viajar de maneras especiales. Se nos permite viajar en cualquier rayo que provenga del origen.

Rayos en los que podemos viajar

También podemos viajar en cualquier círculo centrado en un círculo

Círculos en los que podemos viajar

Ahora nuestro objetivo es viajar de un punto de este avión a otro. Sin embargo, no podemos simplemente viajar en un sendero euclidiano simple, solo podemos hacer esto si los puntos caen en un rayo que emana del centro.

ingrese la descripción de la imagen aquí

Podemos viajar en este porque cae en uno de nuestros rayos.

ingrese la descripción de la imagen aquí

También podemos viajar en círculos centrados en el origen.

ingrese la descripción de la imagen aquí

Ejemplos

Ahora aquí está el desafío:

Tenemos que ir de un punto a otro en el camino más corto; a menudo es una combinación de viajar en círculos y rayos.

ingrese la descripción de la imagen aquí

Esto, sin embargo, también podría estar viajando en dos rayos.

ingrese la descripción de la imagen aquí

A veces existen dos caminos que recorren la distancia mínima.

ingrese la descripción de la imagen aquí

Problema

Su desafío es escribir un programa que cuando se le den dos puntos nos dará la distancia mínima entre ellos si seguimos estas reglas. Las entradas se pueden dar en forma rectangular o polar y la salida debe ser un número, la distancia entre ellos.

Casos de prueba

(con entrada rectangular)

(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
Ando Bando
fuente
¿Son los ejemplos de casos de prueba en formas rectangulares o polares? También: bewteen
Angs
Están en forma rectangular, debo aclarar eso
Ando Bando
¿Es correcto el último ejemplo? Estoy obteniendo ~ 3.166
Angs
66
@ Peter Taylor Porque no son realmente el mismo camino. De manera similar, una ruta de 0,0 a 1,1 en el plano xy a través de pequeños pasos que alternan en las direcciones x e y parece idéntica a una ruta diagonal directa ya que la longitud del paso tiende a cero. Pero la ruta diagonal tiene longitud sqrt (2) mientras que la ruta de paso siempre tendrá longitud 2.
Penguino
1
Creo que el desafío se vería mejor si las imágenes no fueran tan grandes. Actualmente hacen que sea difícil seguir el texto
Luis Mendo

Respuestas:

5

Haskell, 49 48 bytes

(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

Gracias a @Zgarb por guardar un byte

Angs
fuente
Puede guardar un byte definiendo en (a!q)c rlugar de d a q c r.
Zgarb
4

JavaScript (ES6), 65 bytes

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

Toma coordenadas polares. Utiliza el truco de @Angs para reducir un ángulo entre 0 y π. Para coordenadas rectangulares, algo como esto funciona:

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))
Neil
fuente
3

MATL , 22 bytes

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

La entrada es una matriz de dos números complejos.

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

|       % 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
Luis Mendo
fuente
2

Ruby, 64 bytes

Primero, mi sumisión. Función lambda con argumentos 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}

Ahora aquí hay dos soluciones diferentes de 66 bytes (excluyendo la asignación f=) seguidas de mi envío real nuevamente a 64 bytes.

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}

El envío se basa en la solución 2, pero utiliza la identidad (s-r).abs= s+r-[s,r].min*2para acortar el código en 2 bytes, de ahí el -2interior de los corchetes.

La otra característica notable es la expresión ?i.to_c.arg*4= 2 * PI sin usar include Math. Si se acepta una precisión menor, esto puede ser reemplazado por un literal.

Solución 2 comentada en el programa de prueba

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

Salida

2.221441469079183
1.4142135623730951
1.9999342590038496
1.1996117257705434
3.1660966740274357
Level River St
fuente
2

Mathematica 66 Bytes

Esto toma coordenadas rectangulares y puede generar una solución simbólica exacta

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

rendimientos: resultado simbólico

N @% rendimientos:

{2.221441469, 1.414213562, 1.999934259, 1.199611726, 3.166096674}

Kelly Lowder
fuente
1
¡Hábil! Si va por la ruta simbólica, puede reemplazar el caso de prueba {1,0} {-. 4161, .90929} con {1,0} {cos (2), sin (2)}
Ando Bando
1

Python 2, 164 126 125 132 bytes:

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)

Sin embargo, actualmente estoy estudiando esto más. Acepta coordenadas polares. Debe llamarse en el formato A(r1,θ1,r2,θ2). Emite un valor de coma flotante preciso hasta 12cifras significativas.

¡Pruébelo en línea! (Ideona)

Una implementación simple y directa que calcula y genera en STDOUT el valor mínimo de una matriz de como máximo 3 valores que contienen:

  1. el valor mínimo de la suma de las dos longitudes ( r1+r2) o la longitud del arco que conecta los dos puntos iff r1==r2 ;
  2. la diferencia entre las dos distancias ( abs(r1-r2)) iff θ1==θ2 (es decir, los dos puntos son colineales);
  3. si no se agrega ninguno de los 2 elementos anteriores, entonces una cadena vacía ( '') como aparentemente en Python una cadena es mayor que cualquier número entero;
  4. y 2 valores finales dados a partir de las distancias recorridas a lo largo de un círculo y un rayo y viceversa entre los dos puntos.
R. Kap
fuente
¿Por qué no math.pi?
user202729
0

Wolfram Language (Mathematica) , 47 bytes

MinMax@Abs@{##}.{Min[Abs[Arg@#-Arg@#2]-1,1],1}&

Pruébalo en línea!

(supera la respuesta actual de 66 bytes)

Tome la entrada como 2 números complejos.

Puede tener algunos problemas si la entrada es simbólica. (por ejemplo, Cos@2 + I Sin@2)

usuario202729
fuente