Dada la latitud / longitud de dos puntos en la Luna (lat1, lon1)
y (lat2, lon2)
, calcule la distancia entre los dos puntos en kilómetros, usando cualquier fórmula que dé el mismo resultado que la fórmula de Haversine.
Entrada
- Cuatro valores enteros
lat1, lon1, lat2, lon2
en grados (ángulo) o - cuatro valores decimales
ϕ1, λ1, ϕ2, λ2
en radianes.
Salida
Distancia en kilómetros entre los dos puntos (decimal con cualquier precisión o número entero redondeado).
Fórmula de Haversine
dónde
r
es el radio de la esfera (suponga que el radio de la Luna es de 1737 km),ϕ1
latitud del punto 1 en radianesϕ2
latitud del punto 2 en radianesλ1
longitud del punto 1 en radianesλ2
longitud del punto 2 en radianesd
es la distancia circular entre los dos puntos
(fuente: https://en.wikipedia.org/wiki/Haversine_formula )
Otras posibles fórmulas
d = r * acos(sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1))
fórmula de @miles .d = r * acos(cos(ϕ1 - ϕ2) + cos ϕ1 cos ϕ2 (cos(λ2 - λ1) - 1))
La fórmula de @Neil .
Ejemplo donde las entradas son grados y la salida como entero redondeado
42, 9, 50, 2 --> 284
50, 2, 42, 9 --> 284
4, -2, -2, 1 --> 203
77, 8, 77, 8 --> 0
10, 2, 88, 9 --> 2365
Reglas
- La entrada y la salida se pueden dar en cualquier formato conveniente .
- Especifique en la respuesta si las entradas están en grados o radianes .
- No es necesario manejar valores de latitud / longitud no válidos
- Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
- Si es posible, incluya un enlace a un entorno de prueba en línea para que otras personas puedan probar su código.
- Las lagunas estándar están prohibidas.
- Este es el código de golf, por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
code-golf
math
geometry
trigonometry
mdahmoune
fuente
fuente
d = r * acos( sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1) )
donder = 1737
Respuestas:
Wolfram Language (Mathematica) , 48 bytes
Pruébalo en línea!
Utiliza la fórmula
d = r * acos( sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1) )
donder = 1737
fuente
R + geosfera ,
5447 bytesPruébalo en línea!
Toma la entrada como vectores de 2 elementos
longitude,latitude
en grados. TIO no tiene elgeosphere
paquete, pero puede estar seguro de que devuelve resultados idénticos a la función a continuación.Gracias a Jonathan Allan por reducir 7 bytes.
R , 64 bytes
Pruébalo en línea!
Toma 4 entradas como en los casos de prueba, pero en radianes en lugar de grados.
fuente
e3
y/1000
realmente necesarios?JavaScript (Node.js) , 65 bytes
Pruébalo en línea!
Basado en la respuesta de Kevin Cruijssen, los comentarios de Miles y Neil, y a pedido de Arnauld.
fuente
JavaScript (ES7), 90 bytes
Nota: vea la publicación de @ OlivierGrégoire para una solución mucho más corta
Un puerto directo de la respuesta de TFeld . Toma entrada en radianes.
Pruébalo en línea!
Usando el infame
with()
, 85 bytesGracias a @ l4m2 por guardar 6 bytes
Pruébalo en línea!
fuente
with(Math)f=(a,b,c,d)=>3474*asin((sin((c-a)/2)**2+cos(c)*cos(a)*sin((d-b)/2)**2)**.5)
(a,b,c,d,M=Math)=>1737*M.acos(M.sin(a)*M.sin(c)+M.cos(a)*M.cos(c)*M.cos(d-b))
(a,b,c,d,M=Math)=>1737*M.acos(M.cos(a-c)+M.cos(a)*M.cos(c)*(M.cos(d-b)-1))
(a,b,c,d,C=Math.cos)=>1737*Math.acos(C(a-c)+C(a)*C(c)*(C(d-b)-1))
APL (Dyalog Unicode) ,
4035 bytes SBCSFunción tácita anónima. Toma {ϕ₁, λ₁} como argumento izquierdo y {ϕ₂, λ₂} como argumento derecho.
Utiliza la fórmula 2 r √ (sin² ( (ϕ₁-ϕ₂) ⁄ 2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂) ⁄ 2 ))
Pruébalo en línea! (la
r
función convierte grados a radianes),¨
concatenar elementos correspondientes; {{ϕ₁, ϕ₂}, {λ₁, λ₂}}⊃
escoge el primero; {ϕ₁, ϕ₂}∘
entonces2×.○
producto de sus cosenos; cos ϕ₁ cos ϕ₂encendido. punto "producto" pero con selector de función trigonométrica (2 es coseno) en lugar de multiplicación y tiempos en lugar de más
1,
anteponer 1 a eso; {1, cos ϕ₁ cos ϕ₂}(
…)×
Multiplique eso por el resultado de aplicar la siguiente función a {ϕ₁, λ₁} y {ϕ₂, λ₂}:-
sus diferencias {ϕ₁ - ϕ₂, λ₁ - λ₂}2÷⍨
dividir eso por 2; { (ϕ₁ - ϕ₂) ⁄ 2 , (λ₁ - λ₂) ⁄ 2 }1○
seno de eso; {sin ( (ϕ₁ - ϕ₂) ⁄ 2 ), sin ( (λ₁ - λ₂) ⁄ 2 )}×⍨
cuadrado que (lit. auto-multiplicar); {sin² ( (ϕ₁ - ϕ₂) ⁄ 2 ), sin² ( (λ₁-λ₂) ⁄ 2 )}Ahora tenemos {sin² ( (ϕ₁ - ϕ₂) ⁄ 2 ), cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂) ⁄ 2 )}
1⊥
suma que (lit. evaluar en base-1); sin² ( (ϕ₁-ϕ₂) ⁄ 2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂) ⁄ 2 ).5*⍨
raíz cuadrada de eso (literalmente, eleva eso a la potencia de la mitad)¯1○
arcoseno de eso3474×
multiplica eso por estoLa función para permitir la entrada en grados es:
÷180
argumento dividido por 180○
multiplicar por πfuente
Python 2 , 95 bytes
Pruébalo en línea!
Toma entrada en radianes.
Versión anterior, antes de que la E / S se aflojara: toma la entrada como grados enteros y devuelve dist redondeado
Python 2 , 135 bytes
Pruébalo en línea!
fuente
int
yround
dado que los decimales están permitidos como salida, también puede evitar la conversión a radianes porque las entradas como radianes también están permitidasJava 8,
113928882 bytesLas entradas
a,b,c,d
estánϕ1,λ1,ϕ2,λ2
en radianes.-21 bytes usando la fórmula más corta de @miles .
-4 bytes gracias a @ OlivierGrégore porque todavía lo usaba
{Math m=null;return ...;}
con cadaMath.
asm.
, en lugar de soltarloreturn
y usarloMath
directamente.-6 bytes usando la fórmula más corta de @Neil .
Pruébalo en línea.
Explicación:
fuente
(a,b,c,d)->1737*Math.acos(Math.sin(a)*Math.sin(c)+Math.cos(a)*Math.cos(c)*Math.cos(d-b))
(a,b,c,d)->1737*Math.acos(Math.cos(a-c)+Math.cos(a)*Math.cos(c)*(Math.cos(d-b)-1))
Japt ,
5550 bytesNo necesariamente tan precisa como las otras respuestas, pero vaya si me divertí con esta. Permíteme elaborar.
Si bien en la mayoría de los idiomas, este desafío es bastante sencillo, Japt tiene la desafortunada propiedad de que no hay arcoseno ni arcosina incorporados. Claro, puedes incrustar Javascript en Japt, pero eso sería lo opuesto a Feng Shui.
¡Todo lo que tenemos que hacer para superar esta pequeña molestia es el arcocoseno aproximado y estamos listos para comenzar!
La primera parte es todo lo que se introduce en el arcocoseno.
El resultado se almacena implícitamente
U
para su uso posterior.Después de eso, necesitamos encontrar una buena aproximación para el arcocoseno. Como soy flojo y no soy tan bueno con las matemáticas, obviamente solo lo vamos a forzar.
Podríamos haber usado cualquier número grande para la resolución del generador, las pruebas manuales mostraron que
7!
es lo suficientemente grande y razonablemente rápido.Toma la entrada como radianes, emite números sin redondear.
Afeitado cinco bytes gracias a Oliver .
Pruébalo en línea!
fuente
(
enMc(X-V
. Dado que el código char para1737
no es ISO-8859-1, cambia a UTF-8, que cuesta más. En su lugar, puede usar el código char para173
+7
. ethproductions.github.io/japt/?v=1.4.5&code=I603&input=,
despuésToMP
:-)Haskell ,
68 66 5251 bytesPruébalo en línea!
-1 byte gracias a BMO
fuente
Ruby ,
87 7069 bytesPruébalo en línea!
Ahora usando el método de Neil, gracias a Kevin Cruijssen.
fuente
->a,b,c,d{include Math;1737*acos(cos(a-c)+cos(a)*cos(c)*(cos(d-b)-1))}
Jalea ,
23 2218 bytes-4 bytes gracias a millas (uso de
{
y}
mientras se usa su fórmula .Una función diádica que acepta
[ϕ1, ϕ2,]
a la izquierda y[λ1, λ2]
a la derecha en radianes que devuelve el resultado (como punto flotante).Pruébalo en línea!
Mine ... (también guardé un byte aquí usando a
{
)Pruébalo en línea
fuente
;I}ÆẠP+ÆSP${ÆA×⁽£ġ
{
y}
nunca hacen lo que yo esperaba. ¿No significa eso que puedo hacer lo contrario en 17?{
y}
solo crea una diada a partir de una mónada. Una opinión similar podría serP{ -> ḷP¥
. Podría ser bueno agregar una composición (de J) rápidamente para hacer algo como lox (P+$) y -> (P x) + (P y)
que puede guardar un byte o dos en situaciones similares.MATLAB con Mapping Toolbox, 26 bytes
Función anónima que toma las cuatro entradas como una matriz de celdas, en el mismo orden que se describe en el desafío.
Tenga en cuenta que esto da resultados exactos (suponiendo que el radio de la Luna es de 1737 km), porque
1737/180
es igual9.65
.Ejemplo ejecutado en Matlab R2017b:
fuente
Python 3, 79 bytes
TIO no tiene geopy.py
fuente
APL (Dyalog Unicode) , SBCS de 29 bytes
Programa completo Solicita stdin para {ϕ₁, ϕ₂} y luego para {λ₁, λ₂}. Imprime en stdout.
Utiliza la fórmula r acos (sin ϕ₁ sin ϕ₂ + cos (λ₂ - λ₁) cos ϕ₁ cos ϕ₂)
Pruébalo en línea! (la
r
función convierte grados a radianes)⎕
solicitud de {ϕ₁, ϕ₂}1 2∘.○
Aplicación de función trigonométrica cartesiana; {{sin ϕ₁, sin ϕ₂}, {cos ϕ₁, cos ϕ₂}}×/
productos en hileras; {sin ϕ₁ sin ϕ₂, cos ϕ₁ cos ϕ₂}(
...)×@2
en el segundo elemento, multiplique lo siguiente por eso:⎕
solicitud de {λ₁, λ₂}-/
diferencia entre esos; λ₁ - λ₂2○
coseno de eso; cos (λ₁ - λ₂)Ahora tenemos {sin ϕ₁ sin ϕ₂, cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂}
+/
suma; sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂¯2○
coseno de eso; cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂)1737×
multiplicar r por eso; 1737 cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂)La función para permitir la entrada en grados es:
÷180
argumento dividido por 180○
multiplicar por πfuente
C (gcc) ,
100886564 bytes88 → 65 usando la fórmula de @miles '65
→ 64 usando la fórmula de @ Neil
Pruébalo en línea!
fuente
-lm
indicador del compilador.Excel, 53 bytes
Usando la fórmula de @ Neil. Entrada en radianes.
fuente
Langosta , 66 bytes
Utiliza la fórmula de millas, pero la entrada está en grados. Esto agrega un paso adicional de conversión a radianes antes de multiplicar por radio.
fuente
Python 3 ,
119103bytesEsto usa grados.
Pruébalo en línea!
fuente
1737*acos(cos(a-A)+cos(a)*cos(A)*(cos(O-o)-1))
PHP , 88 bytes
Puerto de Oliver respuesta
Pruébalo en línea!
fuente
SmileBASIC, 60 bytes
fuente