Учитывая широту / долготу двух точек на Луне (lat1, lon1)
и (lat2, lon2)
вычислите расстояние между двумя точками в километрах, используя любую формулу, которая дает тот же результат, что и формула haversine.
вход
- Четыре целых значения
lat1, lon1, lat2, lon2
в градусах (углах) или - четыре десятичных значения
ϕ1, λ1, ϕ2, λ2
в радианах.
Выход
Расстояние в километрах между двумя точками (десятичное с любой точностью или округленное целое число).
Формула Haversine
где
r
- радиус сферы (предположим, что радиус Луны составляет 1737 км),ϕ1
широта точки 1 в радианахϕ2
широта точки 2 в радианахλ1
долгота точки 1 в радианахλ2
долгота точки 2 в радианахd
круговое расстояние между двумя точками
(источник: https://en.wikipedia.org/wiki/Haversine_formula )
Другие возможные формулы
d = r * acos(sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1))
формула @ миль .d = r * acos(cos(ϕ1 - ϕ2) + cos ϕ1 cos ϕ2 (cos(λ2 - λ1) - 1))
@Neil формула «ы .
Пример, где входные данные представляют собой градусы, а выходные данные - округленное целое число
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
правила
- Вход и выход могут быть предоставлены в любом удобном формате .
- Укажите в ответе, являются ли входные данные в градусах или радианах .
- Нет необходимости обрабатывать неверные значения широты / долготы
- Либо полная программа или функция приемлемы. Если функция, вы можете вернуть вывод, а не распечатать его.
- Если возможно, укажите ссылку на среду онлайн-тестирования, чтобы другие люди могли опробовать ваш код!
- Стандартные лазейки запрещены.
- Это код-гольф, поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).
code-golf
math
geometry
trigonometry
mdahmoune
источник
источник
d = r * acos( sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1) )
гдеr = 1737
Ответы:
Wolfram Language (Mathematica) , 48 байтов
Попробуйте онлайн!
Использует формулу
d = r * acos( sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1) )
гдеr = 1737
источник
R + геосфера ,
5447 байтПопробуйте онлайн!
Вводит как 2-элементные векторы
longitude,latitude
в градусах. TIO не имеетgeosphere
пакета, но будьте уверены, что он возвращает идентичные результаты для функции ниже.Спасибо Джонатану Аллану за то, что он сбрил 7 байтов.
R , 64 байта
Попробуйте онлайн!
Принимает 4 входа, как в тестовых случаях, но в радианах, а не в градусах.
источник
e3
И/1000
действительно ли это необходимо?JavaScript (Node.js) , 65 байт
Попробуйте онлайн!
На основании ответа Кевина Круйссена, комментариев Майлза и Нейла и по запросу Арно.
источник
JavaScript (ES7), 90 байт
Примечание: см. Сообщение @ OlivierGrégoire для более короткого решения
Прямой порт ответа Тфельда . Вводит в радианах.
Попробуйте онлайн!
Использование печально известного
with()
, 85 байтСпасибо @ l4m2 за сохранение 6 байтов
Попробуйте онлайн!
источник
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 байт SBCSАнонимная молчаливая функция. Принимает {ϕ₁, λ₁} в качестве левого аргумента и {ϕ₂, λ₂} в качестве правого аргумента.
Использует формулу 2 r √ (sin² ( (ϕ₁-ϕ₂) ⁄ 2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂) ⁄ 2 ))
Попробуйте онлайн! (
r
функция преобразует градусы в радианы),¨
объединить соответствующие элементы; {{ϕ₁, ϕ₂}, {λ₁, λ₂}}⊃
выбрать первое; {ϕ₁, ϕ₂}∘
затем2×.○
произведение их косинусов; cos ϕ₁ cos ϕ₂лит. точка "продукт", но с селектором функции триггера (2 - косинус) вместо умножения и раз вместо плюс
1,
добавьте 1 к этому; {1, cos ϕ₁ cos ϕ₂}(
…)×
Умножьте это на результат применения следующей функции к {ϕ₁, λ₁} и {ϕ₂, λ₂}:-
их различия; {ϕ₁ - ϕ₂, λ₁ - λ₂}2÷⍨
разделите это на 2; { (ϕ₁ - ϕ₂) ⁄ 2 , (λ₁ - λ₂) ⁄ 2 }1○
синус этого; {грех ( (ϕ₁ - ϕ₂) ⁄ 2 ), грех ( (λ₁ - λ₂) ⁄ 2 )}×⍨
возвести в квадрат (лит. умножить себя); {sin² ( (ϕ₁ - ϕ₂) ⁄ 2 ), sin² ( (λ₁-λ₂) ⁄ 2 )}Теперь у нас есть {sin² ( (ϕ₁ - ϕ₂) ⁄ 2 ), cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂) ⁄ 2 )}
1⊥
суммируйте это (лит. оценка в базе-1); sin² ( (ϕ₁-ϕ₂) ⁄ 2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂) ⁄ 2 ).5*⍨
квадратный корень из этого (букв. поднимите это до степени половины)¯1○
арксинус этого3474×
умножьте это на этоФункция разрешения ввода в градусах:
÷180
аргумент делится на 180○
умножить на πисточник
Python 2 , 95 байт
Попробуйте онлайн!
Вводит в радианах.
Старая версия, до того как ввод / вывод был ослаблен: принимает ввод как целые градусы и возвращает округленное расстояние
Python 2 , 135 байт
Попробуйте онлайн!
источник
int
иround
поскольку десятичные дроби разрешены в качестве выходных данных, вы также можете избежать преобразования в радианы, потому что входные данные в радианах также допускаютсяJava 8,
113928882 байтаВходы
a,b,c,d
находятсяϕ1,λ1,ϕ2,λ2
в радианах.-21 байт, используя более короткую формулу @miles .
-4 байта благодаря @ OlivierGrégore, потому что я все еще использовал
{Math m=null;return ...;}
с каждымMath.
asm.
, вместо того, чтобы удалятьreturn
и использоватьMath
напрямую.-6 байт, используя более короткую формулу @Neil .
Попробуйте онлайн.
Объяснение:
источник
(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 байтНе обязательно так же точно, как другие ответы, но парень, я развлекался с этим. Позвольте мне уточнить.
В то время как в большинстве языков эта задача довольно проста, у Japt есть прискорбное свойство - нет ни встроенного арксинуса, ни арккозина. Конечно, вы можете встраивать Javascript в Japt, но это будет то, что всегда является противоположностью фэн-шуй.
Все, что нам нужно сделать, чтобы преодолеть эту небольшую неприятность, - это приблизительный арккозин, и мы готовы к работе!
Первая часть - это все, что подается в арккозин.
Результат неявно сохраняется
U
для последующего использования.После этого нам нужно найти хорошее приближение для арккозина. Поскольку я ленивый и не очень хорошо разбираюсь в математике, мы, очевидно, просто собираемся его перебить.
Мы могли бы использовать любое большое число для разрешения генератора, ручное тестирование показало, что
7!
оно достаточно большое, но достаточно быстрое.Принимает входные данные в радианах, выводит незаземленные числа.
Скинул пять байтов благодаря Оливеру .
Попробуйте онлайн!
источник
(
вMc(X-V
. Поскольку код символа1737
не соответствует ISO-8859-1, он переключается на UTF-8, который стоит дороже. Вместо этого вы можете использовать код173
+ для +7
. ethproductions.github.io/japt/?v=1.4.5&code=I603&input=,
послеToMP
:-)Haskell ,
68 66 5251 байтПопробуйте онлайн!
-1 байт благодаря BMO
источник
Рубин ,
87 7069 байтПопробуйте онлайн!
Теперь, используя метод Нейла, спасибо Кевину Круйссену.
источник
->a,b,c,d{include Math;1737*acos(cos(a-c)+cos(a)*cos(c)*(cos(d-b)-1))}
Желе ,
23 2218 байт-4 байта благодаря милям (использование
{
и}
при использовании их формулы .Двоичная функция, принимаемая
[ϕ1, ϕ2,]
слева и[λ1, λ2]
справа в радианах, которая возвращает результат (в виде числа с плавающей запятой).Попробуйте онлайн!
Мой ... (также сохранил байт здесь, используя
{
)Попробуйте онлайн
источник
;I}ÆẠP+ÆSP${ÆA×⁽£ġ
{
и}
они никогда не делают то, что я ожидал. Разве это не значит, что я могу поступить иначе в 17 лет ?!{
и}
просто создать диаду из монады. Аналогичная точка зрения может бытьP{ -> ḷP¥
. Возможно, было бы неплохо добавить композицию (из J), чтобы быстро сделать что-то подобное,x (P+$) y -> (P x) + (P y)
что может сохранить один или два байта в похожих ситуациях.MATLAB с Mapping Toolbox, 26 байтов
Анонимная функция, которая принимает четыре входа в виде массива ячеек в том же порядке, как описано в задании.
Обратите внимание, что это дает точные результаты (при условии, что радиус Луны составляет 1737 км), потому что
1737/180
равен9.65
.Пример запуска в Matlab R2017b:
источник
Python 3, 79 байт
TIO не имеет geopy.py
источник
APL (Dyalog Unicode) , 29 байтов SBCS
Полная программа. Запрашивает стандартный ввод для {ϕ₁, ϕ₂}, а затем для {λ₁, λ₂}. Печать на стандартный вывод.
Используется формула r acos (sin ϕ₁ sin ϕ₂ + cos (λ₂ - λ₁) cos ϕ₁ cos ϕ₂)
Попробуйте онлайн! (
r
функция преобразует градусы в радианы)⎕
запросить {ϕ₁, ϕ₂}1 2∘.○
Приложение декартовой триг-функции; {{sin ϕ₁, sin ϕ₂}, {cos ϕ₁, cos ϕ₂}}×/
рядные продукты; {sin ϕ₁ sin ϕ₂, cos ϕ₁ cos ϕ₂}(
…)×@2
На втором элементе умножьте на это следующее:⎕
запросить {λ₁, λ₂}-/
разница между ними; λ₁ - λ₂2○
косинус этого; cos (λ₁ - λ₂)Теперь у нас есть {sin ϕ₁ sin ϕ₂, cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂}
+/
просуммировать; sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂¯2○
косинус этого; cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂)1737×
умножьте r на это; 1737 cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂)Функция разрешения ввода в градусах:
÷180
аргумент делится на 180○
умножить на πисточник
C (gcc) ,
100886564 байта88 → 65 с использованием формулы @miles
65 → 64 с использованием формулы @ Neil
Попробуйте онлайн!
источник
-lm
флага компилятора.Excel, 53 байта
Используя формулу @ Neil. Ввод в радианах.
источник
Омар , 66 байт
Использует формулу миль, но ввод в градусах. Это добавляет дополнительный шаг преобразования в радианы перед умножением на радиус.
источник
Python 3 ,
119103 байтаЭто использует градусы.
Попробуйте онлайн!
источник
1737*acos(cos(a-A)+cos(a)*cos(A)*(cos(O-o)-1))
PHP , 88 байт
Порт Оливера ответ
Попробуйте онлайн!
источник
SmileBASIC, 60 байтов
источник