달의 두 지점 사이의 거리


11

(lat1, lon1)과 위의 두 점의 위도 / 경도가 주어지면 , 허세 인 공식과 동일한 결과를 제공하는 공식(lat2, lon2)사용하여 두 지점 사이의 거리를 킬로미터 단위로 계산하십시오 .

입력

  • lat1, lon1, lat2, lon2도 (각도)의 4 개의 정수 값 또는
  • ϕ1, λ1, ϕ2, λ2라디안으로 된 소수점 이하 4 자리 .

산출

두 점 사이의 거리 (킬로미터) (정밀도 또는 반올림 된 정수로 10 진수).

Haversine 공식

d = 2 r \ arcsin \ left (\ sqrt {\ sin ^ 2 \ left (\ frac {\ phi_2-\ phi_1} {2} \ right) + \ cos (\ phi_1) \ cos (\ phi_2) \ sin ^ 2 \ 왼쪽 (\ frac {\ lambda_2-\ lambda_1} {2} \ right)} \ right)

어디

  • r 구의 반경입니다 (달의 반경이 1737km라고 가정).
  • ϕ1 라디안 포인트 1의 위도
  • ϕ2 라디안 포인트 2의 위도
  • λ1 라디안 단위 1의 경도
  • λ2 라디안 단위 2의 경도
  • d 두 점 사이의 원형 거리입니다

(출처 : https://en.wikipedia.org/wiki/Haversine_formula )

다른 가능한 공식

입력이도이고 반올림 된 정수로 출력되는 예

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

규칙

  • 입력 및 출력은 편리한 형식으로 제공 될 수 있습니다 .
  • 입력 값이 단위 인지 라디안 인지를 답에 지정하십시오 .
  • 잘못된 위도 / 경도 값 을 처리 할 필요가 없습니다.
  • 전체 프로그램 또는 기능이 허용됩니다. 함수 인 경우 출력하지 않고 출력을 반환 할 수 있습니다.
  • 가능하면 다른 사람들이 귀하의 코드를 시험해 볼 수 있도록 온라인 테스트 환경에 대한 링크를 포함하십시오!
  • 표준 허점 은 금지되어 있습니다.
  • 이것은 이므로 모든 일반적인 골프 규칙이 적용되며 가장 짧은 코드 (바이트)가 이깁니다.

7
이 특정 공식을 사용하는 것은 관찰 할 수없는 요구 사항입니다. 그것은 그 공식이 같은 결과를 제공하는 것만으로는 충분하지 않습니다 것입니다 줄을?
Adám

1
라디안으로 입력을 받아도 될까요?
Adám

1
OK @mdahmoune, 그래서 당신은 쓰기의 용이성 정도에 나와 있지만, 우리는 라디안으로 입력이 필요? 그렇지 않으면이 도전은 각도 변환과 주요 도전의 결합 (나쁜)이됩니다.
Adám

5
이 질문은 '누구의 언어로이 공식을 가장 많이 활용할 수 있는가'로 보이므로이 질문을 하향 조정했습니다.
caird coinheringaahing

2
대부분의 언어에 대한 더 짧은 공식은 다음과 같습니다 d = r * acos( sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1) ).r = 1737
마일

답변:



6

R + 지구권 , 54 47 바이트

function(p,q)geosphere::distHaversine(p,q,1737)

온라인으로 사용해보십시오!

입력을 longitude,latitude도 단위의 요소를 2 개 가진 벡터로 취합니다 . TIO에는 geosphere패키지가 없지만 아래의 함수에 동일한 결과를 반환하므로 안심하십시오.

7 바이트를 줄여준 Jonathan Allan에게 감사합니다.

R , 64 바이트

function(p,l,q,k)1737*acos(sin(p)*sin(q)+cos(p)*cos(q)*cos(k-l))

온라인으로 사용해보십시오!

테스트 사례에서와 같이 4 개 입력을 사용하지만 도가 아닌 라디안으로 입력합니다.


인가 e3와는 /1000정말 필요한?
Jonathan Allan

1
@JonathanAllan 아니에요. 그것은 저의 멍청한 일이지만 반지름의 기본 논거는 지구의 미터입니다. 당시에는 논리적이었습니다. lol
Giuseppe

코사인의 구형 법칙은 특히 작은 거리에서 수치 적으로 안정적이지 않습니다. 아마도 Mathematica 에서는 괜찮을 것입니다 . 그러나 R 및 대부분의 다른 언어에서는 "허 더신 공식과 동일한 결과를 제공하는 공식"기준이 충족되는지 여부에 대해서는 논란의 여지가 있습니다.
반 시계 회전을 중지

@ceasedtoturncounterclockwis 기본 R에 사용하기 위해 주로 포함 시켰습니다. 임의의 정밀 부동 소수점 라이브러리를 사용하면 효과가 완화되는 것으로 가정합니다.
Giuseppe

예, 또는 예를 들어, haversine 공식과 같은 안정적인 공식을 사용하는 것
시계 반대 방향으로 돌리는 것을 중단했습니다.


5

자바 스크립트 (ES7), 90 바이트

참고 : 훨씬 짧은 솔루션 은 @ OlivierGrégoire의 게시물 을 참조하십시오

TFeld 's answer 의 직접적인 항구 . 라디안으로 입력을받습니다.

(a,b,c,d,M=Math)=>3474*M.asin((M.sin((c-a)/2)**2+M.cos(c)*M.cos(a)*M.sin((d-b)/2)**2)**.5)

온라인으로 사용해보십시오!

악명 높은 with()85 바이트 사용

6 바이트를 절약 한 @ l4m2 덕분에

with(Math)f=(a,b,c,d)=>3474*asin((sin((c-a)/2)**2+cos(c)*cos(a)*sin((d-b)/2)**2)**.5)

온라인으로 사용해보십시오!


2
당신은 할 수 있습니다with(Math)f=(a,b,c,d)=>3474*asin((sin((c-a)/2)**2+cos(c)*cos(a)*sin((d-b)/2)**2)**.5)
l4m2

@miles '더 짧은 알고리즘을 사용하는 77 바이트 :(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))
Kevin Cruijssen

1
바이트 74 사용 @Neil는 "짧은 알고리즘 S는 :(a,b,c,d,M=Math)=>1737*M.acos(M.cos(a-c)+M.cos(a)*M.cos(c)*(M.cos(d-b)-1))
케빈 Cruijssen에게

3
모든 사람의 대답을 최적화하는 65 바이트 :(a,b,c,d,C=Math.cos)=>1737*Math.acos(C(a-c)+C(a)*C(c)*(C(d-b)-1))
Olivier Grégoire

@ OlivierGrégoire 아주 좋아요. 아마 새로운 답변으로 게시해야합니다.
Arnauld

5

APL (Dyalog Unicode) , 40 35 바이트 SBCS

익명의 암묵적 기능. {argument, λ₁}를 왼쪽 인수로 사용하고 {ϕ₂, λ₂}를 오른쪽 인수로 사용합니다.

공식 2 r √ (sin² ( (ϕ₁-ϕ₂)2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ – λ₂)2 ) 사용)

3474ׯ1○.5*⍨1⊥(×⍨12÷⍨-)×1,2×.○∘⊃,¨

온라인으로 사용해보십시오! (이 r함수는 각도를 라디안으로 변환합니다)


 대응하는 요소를 연결하고; {{ϕ₁, ϕ₂}, {λ₁, λ₂}}

 첫 번째를 고르세요; {ϕ₁, ϕ₂}

 그때

2×.○ 그들의 코사인의 산물; cos ϕ₁ cos ϕ₂
점등. 점 "제품"이지만 곱하기 대신 삼각 함수 선택기 (2는 코사인)와 플러스 대신 시간

1, 그 앞에 1을 붙이십시오. {1, cos ϕ₁ cos ϕ₂}

( 다음 함수를 {ϕ₁, λ₁} 및 {ϕ₂, λ₂}에 적용한 결과에 곱하십시오.

- 그들의 차이점; {ϕ₁-ϕ₂, λ₁-λ₂}

2÷⍨ 이것을 2로 나눕니다. { (ϕ₁-ϕ₂)2 , (λ₁-λ₂)2 }

1○ 그것의 사인; {sin ( (ϕ₁-ϕ₂)2 ), sin ( (λ₁-λ₂)2 )}

×⍨ 정사각형 (lit. self-multiply); {sin² ( (ϕ₁-ϕ₂)2 ), sin² ( (λ₁-λ₂)2 )}

이제 우리는 {sin² ( (ϕ₁-ϕ₂)2 ), cos ϕ₁ cos ϕ₂ sin² ( (λ₁-λ₂)2 )}

1⊥ 그것을 합산한다 (1 단계에서 조명 평가); sin² ( (ϕ₁-ϕ₂)2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁-λ₂)2 )

.5*⍨ 그것의 제곱근 (점등을 반으로 제곱)

¯1○ 그것의 아크 사인

3474× 이것을 곱하면


각도 입력을 허용하는 기능은 다음과 같습니다.

○÷∘180

÷180 인수를 180으로 나눈 값

 π를 곱하다


4

파이썬 2 , 95 바이트

lambda a,b,c,d:3474*asin((sin((c-a)/2)**2+cos(c)*cos(a)*sin((d-b)/2)**2)**.5)
from math import*

온라인으로 사용해보십시오!

라디안으로 입력을받습니다.


I / O가 느슨해지기 전의 이전 버전 : 입력을 정수로 취하고 둥근 dist를 반환

파이썬 2 , 135 바이트

lambda a,b,c,d:int(round(3474*asin((sin((r(c)-r(a))/2)**2+cos(r(c))*cos(r(a))*sin((r(d)-r(b))/2)**2)**.5)))
from math import*
r=radians

온라인으로 사용해보십시오!


드롭 할 수 int있고 round소수는 출력으로 허용되므로 라디안으로 입력도 허용되므로 라디안으로의 변환을 피할 수 있습니다.
mdahmoune

@mdahmoune, 감사합니다, 업데이트
TFeld

3

Java 8, 113 92 88 82 바이트

(a,b,c,d)->1737*Math.acos(Math.cos(a-c)+Math.cos(a)*Math.cos(c)*(Math.cos(d-b)-1))

입력 a,b,c,dϕ1,λ1,ϕ2,λ2라디안입니다.

@miles 의 더 짧은 공식을 사용하는 -21 바이트 . @ OlivierGrégore
덕분에 -4 바이트 덕분에를 삭제하지 않고 모든 as 와 함께 사용했기 때문에 직접 사용 합니다. @Neil 의 더 짧은 공식을 사용하는 -6 바이트 .{Math m=null;return ...;}Math.m.returnMath

온라인으로 사용해보십시오.

설명:

(a,b,c,d)->                  // Method with four double parameters and double return-type
  1737*Math.acos(            //  Return 1737 multiplied with the acos of:
   Math.cos(a-c)             //   the cos of `a` minus `c`,
   +Math.cos(a)*Math.cos(c)  //   plus the cos of `a` multiplied with the cos of `c`
   *(Math.cos(d-b)-1))       //   multiplied with the cos of `d` minus `b` minus 1

1
"조기 최적화는 모든 악의 근원"입니다! 88 바이트 :(a,b,c,d)->1737*Math.acos(Math.sin(a)*Math.sin(c)+Math.cos(a)*Math.cos(c)*Math.cos(d-b))
Olivier Grégoire

" 조기 최적화는 모든 악의 근원 " "정말 맞아요. 감사합니다!
Kevin Cruijssen

1
나는 더 짧은 공식을 발견했다 :(a,b,c,d)->1737*Math.acos(Math.cos(a-c)+Math.cos(a)*Math.cos(c)*(Math.cos(d-b)-1))
Neil

(이 공식은 원래 Wolfram 언어에서는 짧지 않습니다.)
Neil

3

Japt , 55 50 바이트

MsU *MsW +McU *McW *McX-V
ToMP1/7l¹ñ@McX aUÃv *#­7

반드시 다른 답변만큼 정확하지는 않지만 소년은이 답변을 즐겼습니다. 좀 더 자세히 설명하겠습니다.
대부분의 언어에서이 문제는 매우 간단하지만 Japt는 아크 사인이나 아크 코사인에 내장되어 있지 않은 불행한 속성을 가지고 있습니다. 물론, Japt에 Javascript를 포함시킬 수 있지만, Feng Shui의 반대가 될 것입니다.

이 작은 방해 요소를 극복하기 위해해야 ​​할 일은 대략적인 아크 코사인이며 우리는 가도 좋습니다!

첫 번째 부분은 아크 코사인에 공급되는 모든 것입니다.

MsU *MsW +McU *McW *McX-V
MsU                        // Take the sine of the first input and
    *MsW...                // multiply by the cos of the second one etc.

결과는 U나중에 사용하기 위해 암시 적으로 저장됩니다 .

그런 다음 arccosine에 대한 근사치를 찾아야합니다. 나는 게으르고 수학에 능숙하지 않기 때문에 분명히 우리는 그것을 무차별하게 강제 할 것입니다.

ToMP1/7l¹ñ@McX aUÃv *#­7
T                       // Take 0
 o                      // and create a range from it
  MP                    // to π
    1/7l¹               // with resolution 1/7!.
         ñ@             // Sort this range so that
           McX          // the cosine of a given value
               aU       // is closest to U, e.g. the whole trig lot
                        // we want to take arccosine of.
                 Ã      // When that's done,
                  v     // get the first element
                    *#­7 // and multiply it by 1737, returning implicitly.

우리는 발전기 분해능을 위해 많은 수를 사용할 수 있었으며, 수동 테스트는 7!상당히 빠르면서도 충분히 큽니다.

라디안으로 입력을 받고 반올림되지 않은 숫자를 출력합니다.

Oliver 덕분에 5 바이트를 줄 였습니다.

온라인으로 사용해보십시오!


당신은 제거 할 수 (있는가 Mc(X-V. 의 문자 코드 1737는 ISO-8859-1이 아니기 때문에 UTF-8로 전환하는데 비용이 더 많이 듭니다. 대신 173+ 문자 코드를 사용할 수 있습니다 7. ethproductions.github.io/japt/?v=1.4.5&code=I603&input=
Oliver

또한 제거 할 수 있습니다 ,ToMP:-)
올리버

@Oliver 정말 고마워요, 괄호는 원래 버전에서 필요했지만 골프를 칠 때 쓸모가 없어졌습니다. 또한 인코딩에 대해 몰랐습니다. 고마워요.
Nit

1
JavaScript 경로를 사용하려면 shoco를 통해 모든 것을 실행할 수 있습니다.
Oliver



2

젤리 ,  23 22  18 바이트

-4 마일 덕분에 (사용 바이트 {}사용하는 동안 자신의 공식을 .

;I}ÆẠP+ÆSP${ÆA×⁽£ġ

결과를 반환하는 부동 소수점으로 [ϕ1, ϕ2,]왼쪽과 [λ1, λ2]오른쪽을 라디안으로 받아들이 는 2 차원 함수 입니다.

온라인으로 사용해보십시오!


내 ... (또한를 사용하여 바이트를 저장했습니다 {)

,IÆẠCH;ÆẠ{Ḣ+PƊ½ÆṢ×⁽µṣ

온라인으로 사용해보십시오


흥미 롭습니다. 페이지를 다시 새로 고쳤으며 새 답변을 클릭하여 변경 사항을 표시해도 수정 사항이 표시되지 않습니다. 18 바이트 대안은;I}ÆẠP+ÆSP${ÆA×⁽£ġ
마일

사용하는 방법을 이해하지 마십시오 {그리고 }그들은 내가 기대하는 일을하지 않았다. 17 일에 다른 방법으로 할 수있는 건가요?!
Jonathan Allan

아마도. {그리고 }단지 모나드에서 양자 관계를 만들 수 있습니다. 비슷한보기가 될 수 있습니다 P{ -> ḷP¥. 비슷한 상황에서 한두 바이트를 절약 할 수 있는 것과 같은 작업을 수행하기 위해 J에서 작곡을 빠르게 추가하는 것이 좋습니다 x (P+$) y -> (P x) + (P y).
마일

2

매핑 도구 상자가있는 MATLAB, 26 바이트

@(x)distance(x{:})*9.65*pi

문제에 설명 된 것과 동일한 순서로 네 개의 입력을 셀형 배열로 사용하는 익명 함수입니다.

달 반경이 1737km라고 가정하면 정확한 결과를 얻을 수 있습니다. 1737/180 같기9.65 .

Matlab R2017b에서 실행 예제 :

여기에 이미지 설명을 입력하십시오


1

파이썬 3, 79 바이트

from geopy import*
lambda a,b:distance.great_circle(a,b,radius=1737).kilometers

TIO에는 geopy.py가 없습니다


2
@Nit, 내 이해는 질문보다 먼저 공개적으로 사용 가능한 라이브러리를 사용하는 것이 공정한 게임이라는 것입니다. MATLAB의 매핑 도구를 사용하거나 수학 라이브러리를 사용하는 다른 언어를 사용하는 것과 같습니다.
RootTwo

1

APL (Dyalog Unicode) , 29 바이트 SBCS

완전한 프로그램. stdin에게 {ϕ₁, ϕ₂}을 요청한 다음 {λ₁, λ₂}을 입력하라는 프롬프트를 표시합니다. stdout으로 인쇄합니다.

공식 r acos (sin ϕ₁ sin ϕ₂ + cos (λ₂ – λ₁) cos ϕ₁ cos ϕ₂)를 사용합니다.

1737ׯ2○+/(2○-/⎕)×@2×/1 2∘.○⎕

온라인으로 사용해보십시오! (그만큼r함수는 각도를 라디안으로 변환합니다)


 {ϕ₁, ϕ₂}에 대한 프롬프트

1 2∘.○ 직교 삼각 함수 적용; {{sin ϕ₁, sin ϕ₂}, {cos ϕ₁, cos ϕ₂}}

×/ 행 단위 제품; {sin ϕ₁ sin ϕ₂, cos ϕ₁ cos ϕ₂}

()×@2 두 번째 요소에서 다음을 곱하십시오.

 {λ₁, λ₂}에 대한 프롬프트

-/ 그들 사이의 차이; λ₁ – λ₂

2○ 그것의 코사인; cos (λ₁ – λ₂)

이제 우리는 {sin ϕ₁ sin ϕ₂, cos (λ₁ – λ₂) cos s cos ϕ₂}

+/ 합집합; sin ϕ₁ sin ϕ₂ + cos (λ₁ – λ₂) cos ϕ₁ cos ϕ₂

¯2○ 그것의 코사인; cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ – λ₂) cos ϕ₁ cos ϕ₂)

1737× r에 그 값을 곱하십시오; 1737 cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ – λ₂) cos ϕ₁ cos ϕ₂)


각도 입력을 허용하는 기능은 다음과 같습니다.

○÷∘180

÷180 인수를 180으로 나눈 값

 π를 곱하다


1

C (gcc) , 100 88 65 64 바이트

88 → 65 사용 @miles '공식
사용 → 64 (65) 닐의 공식 @

#define d(w,x,y,z)1737*acos(cos(w-y)+cos(w)*cos(y)*(cos(z-x)-1))

온라인으로 사용해보십시오!


-lm컴파일러 플래그에 2 바이트를 추가해야한다고 생각합니다 .
OOBalance

@OOBalance : 플래그가 항상 필요한 것은 아닙니다. 컴파일러가 시스템에 설치된 방법에 따라 다릅니다.
jxh

좋구나. 이것이 내 대답에 대한 두 바이트를 뺄 수 있음을 의미합니다 : codegolf.stackexchange.com/a/161452/79343 감사합니다.
OOBalance

@OOBalance : 답을 올렸습니다. 나는 또한 내 자신의 솔루션을 제출했습니다.
jxh

좋은. 당신도 옹호했습니다.
OOBalance

1

엑셀, 53 바이트

=1737*ACOS(COS(A1-C1)+COS(A1)*COS(C1)*(COS(D1-B1)-1))

@Neil의 공식을 사용합니다. 라디안으로 입력합니다.


1

랍스터 , 66 바이트

def h(a,c,b,d):1737*radians arccos a.sin*b.sin+a.cos*b.cos*cos d-c

마일의 공식을 사용하지만 입력은도 단위입니다. 이렇게하면 반지름을 곱하기 전에 라디안으로 변환하는 추가 단계가 추가됩니다.




1

SmileBASIC, 60 바이트

INPUT X,Y,S,T?1737*ACOS(COS(X-S)+COS(X)*COS(S)*(COS(T-Y)-1))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.