Ay'daki iki nokta arasındaki mesafe


11

Moon, iki nokta arasında bir enlem / boylam göz önüne alındığında (lat1, lon1)ve (lat2, lon2)kullanılarak, kilometre iki nokta arasındaki mesafeyi hesaplamak bir formül haversinüs formülü olarak aynı sonucu vermektedir.

Giriş

  • lat1, lon1, lat2, lon2Derece (açı) veya dört tamsayı değer
  • ϕ1, λ1, ϕ2, λ2radyan cinsinden dört ondalık değer .

Çıktı

İki nokta arasındaki kilometre cinsinden uzaklık (herhangi bir hassasiyetle veya yuvarlanmış tamsayı ile ondalık).

Haversine formülü

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

nerede

  • r kürenin yarıçapıdır (Ay'ın yarıçapının 1737 km olduğunu varsayın),
  • ϕ1 radyan cinsinden nokta 1'in enlemi
  • ϕ2 radyan cinsinden nokta 2'nin enlemi
  • λ1 radyan cinsinden nokta 1'in boylamı
  • λ2 radyan cinsinden nokta 2'nin boylamı
  • d iki nokta arasındaki dairesel mesafedir

(kaynak: https://en.wikipedia.org/wiki/Haversine_formula )

Diğer olası formüller

Girdilerin derece ve çıktıların yuvarlatılmış tamsayı olduğu örnek

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

kurallar

  • Giriş ve çıkış herhangi bir uygun formatta verilebilir .
  • Cevapta girişlerin derece veya radyan olup olmadığını belirtin .
  • Geçersiz enlem / boylam değerlerini işlemeye gerek yok
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlev varsa, çıktıyı yazdırmak yerine döndürebilirsiniz.
  • Mümkünse, diğer kişilerin kodunuzu deneyebilmesi için lütfen bir çevrimiçi test ortamına bağlantı ekleyin!
  • Standart boşluklar yasaktır.
  • Bu bu nedenle tüm olağan golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

7
Bu özel formülü kullanmak gözlemlenemez bir gerekliliktir. O formülü aynı sonucu verecek şekilde yeterli değil mi olurdu vermek?
Adám

1
Girişi radyan olarak alabilir miyiz?
Adám

1
@mdahmoune Tamam, bu yüzden yazma kolaylığı için derece olarak listelediniz, ancak girdilerin radyan olarak olmasını isteyebilir miyiz? Aksi takdirde, bu zorluk, açı dönüşümünün ve ana zorluğun birleşik (kötüdür) haline gelir.
Adám

5
Bu soruyu reddettim, çünkü bence, özellikle ilginç olmayan 'Dili bu formülü en çok kim golf oynayabilir' gibi görünüyor.
caird coinheringaahing

2
Çoğu dil için daha kısa bir formül d = r * acos( sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1) )nerede olacaktırr = 1737
mil

Yanıtlar:



6

R + jeosfer , 54 47 bayt

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

Çevrimiçi deneyin!

Girdiyi derece olarak 2 elemanlı vektörler olarak alır longitude,latitude. TIO'nun geospherepaketi yok, ancak aşağıdaki işleve aynı sonuçları döndürdüğünden emin olabilirsiniz.

Jonathan Allan'a 7 bayt tıraş ettiği için teşekkürler.

R , 64 bayt

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

Çevrimiçi deneyin!

Test durumlarında olduğu gibi 4 girdi alır, ancak derece yerine radyan olarak.


Are e3ve /1000gerçekten gerekli?
Jonathan Allan

1
@JonathanAllan hayır değiller. Bu benim için çok aptalca, ama yarıçap için varsayılan argüman dünyanın metre cinsindendir, o zaman mantıklıydı, lol
Giuseppe

Kosinüslerin küresel yasasının, özellikle küçük mesafeler için sayısal olarak kararlı olmadığını unutmayın. Mathematica'da muhtemelen sorun yok , ancak R ve diğer birçok dilde "haversin formülü ile aynı sonucu veren herhangi bir formül" ölçütünün karşılanıp karşılanmadığı tartışmalıdır.
counterclockwis açmak için durdu

@ceasedtoturncounterclockwis Çoğunlukla R tabanına sahip olmak uğruna dahil ettim. Sanırım keyfi bir hassas kayan nokta kütüphanesi kullanmak etkiyi hafifletir.
Giuseppe

Evet, ya da örneğin haversin formülü gibi kararlı bir formül kullanarak ...
saat


5

JavaScript (ES7), 90 bayt

Not: Çok daha kısa bir çözüm için @ OlivierGrégoire'ın gönderisine bakın

TFeld'in cevabının doğrudan limanı . Radyan cinsinden girdi alır.

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

Çevrimiçi deneyin!

Kötü şöhretli with(), 85 bayt kullanma

6 bayt tasarruf için @ l4m2 sayesinde

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

Çevrimiçi deneyin!


2
Şunları yapabilirsinizwith(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'in daha kısa algoritmasını kullanan 77 bayt :(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
@Neil'in daha kısa algoritmasını kullanan 74 bayt :(a,b,c,d,M=Math)=>1737*M.acos(M.cos(a-c)+M.cos(a)*M.cos(c)*(M.cos(d-b)-1))
Kevin Cruijssen

3
65 bayt herkesin cevabını optimize ediyor:(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 Çok hoş. Muhtemelen yeni bir cevap olarak göndermelisiniz.
Arnauld

5

APL (Dyalog Unicode) , 40 35 bayt SBCS

Anonim zımni fonksiyonu. {Φ₁, λ₁} 'ı sol argüman olarak ve {ϕ₂, λ₂}' yı sağ argüman olarak alır.

2 r √ formülünü kullanır (sin² ( (ϕ₁-ϕ₂)2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂)2 ))

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

Çevrimiçi deneyin! ( rfonksiyon dereceleri radyana dönüştürür)


 karşılık gelen elemanları birleştirmek; {{ϕ₁, ϕ₂}, {λ₁, λ₂}}

 ilkini seçin; {ϕ₁, ϕ₂}

 sonra

2×.○ kosinüslerinin ürünü; cos ϕ₁ cos ϕ₂
yanıyor. nokta "ürün" ancak çarpma yerine trig fonksiyon seçicisi (2 kosinüs) ve artı yerine çarpma

1, başına 1; {1, cos ϕ₁ cos ϕ₂}

( Bunu {ϕ₁, λ₁} ve {ϕ₂, λ₂} 'a aşağıdaki işlevlerin uygulanmasıyla çarpın:

- farklılıkları; {ϕ₁ - ϕ₂, λ₁ - λ₂}

2÷⍨ bunu 2'ye bölün; { (ϕ₁ - ϕ₂)2 , (λ₁ - λ₂)2 }

1○ bunun sinüsü; {sin ( (ϕ₁ - ϕ₂)2 ), sin ( (λ₁ - λ₂)2 )}

×⍨ kare (aydınlatılmış, kendi kendine çarparak); {sin² ( (ϕ₁ - ϕ₂)2 ), sin² ( (λ₁-λ₂)2 )}

Şimdi {sin² ( (ϕ₁ - ϕ₂)2 ), cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂)2 )} var

1⊥ toplam (baz-1'de değerlendirme); sin² ( (ϕ₁-ϕ₂)2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂)2 )

.5*⍨ bunun karekökü (lit. bunu bir buçuk güce yükselt)

¯1○ bunun kemeri

3474× bunu bununla çarp


Derece olarak girişe izin veren fonksiyon:

○÷∘180

÷180 argüman bölü 180

 π ile çarp


4

Python 2 , 95 bayt

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*

Çevrimiçi deneyin!

Radyan cinsinden girdi alır.


I / o gevşetilmeden önceki eski sürüm: Girdiyi tamsayı derece olarak alır ve yuvarlatılmış dist

Python 2 , 135 bayt

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

Çevrimiçi deneyin!


Eğer bırakın intve roundondalıklar çıktı olarak izin verilmiş olduğundan radyan olarak girişler de izin verilmiş olduğundan, ayrıca radyan dönüşümü önleyebilirsiniz
mdahmoune

@mdahmoune, Teşekkürler, güncellendi
TFeld

3

Java 8, 113 92 88 82 bayt

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

Girdiler a,b,c,dolan ϕ1,λ1,ϕ2,λ2radyan cinsinden.

Miles'in daha kısa formülünü kullanarak -21 bayt .
-4 sayesinde bayt @ OlivierGrégore Hala kullanılan çünkü {Math m=null;return ...;}her ile Math.olduğu gibi m.yerine bırakma, returnve kullanımı Mathile doğrudan. @Neil 'in daha kısa formülü
kullanılarak -6 bayt .

Çevrimiçi deneyin.

Açıklama:

(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
"Erken optimizasyon tüm kötülüklerin köküdür"! 88 bayt:(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

" Erken optimizasyon tüm kötülüğün kökü " Sanırım gerçekten haklısın .. Teşekkürler!
Kevin Cruijssen

1
Daha kısa bir formülasyon buldum:(a,b,c,d)->1737*Math.acos(Math.cos(a-c)+Math.cos(a)*Math.cos(c)*(Math.cos(d-b)-1))
Neil

(Bu formülasyon orijinal Wolfram Dili'nde daha kısa değildir.)
Neil

3

Japt , 55 50 bayt

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

Mutlaka diğer cevaplar kadar kesin değil, ama çocuk bu soru ile eğlendim. Ayrıntıya girmeme izin ver.
Çoğu dilde, bu meydan okuma oldukça basit olsa da, Japt ne arsin ne de arccosine için yerleşik olmayan talihsiz bir özelliğe sahiptir. Tabii, Javascript'i Japt'e gömebilirsiniz, ancak Feng Shui'nin tam tersi bu olurdu.

Bu küçük rahatsızlığın üstesinden gelmek için tek yapmamız gereken yaklaşık arccosine ve gitmekte fayda var!

İlk bölüm, arkosine beslenen her şeydir.

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.

Sonuç, Udaha sonra kullanılmak üzere dolaylı olarak saklanır .

Bunu takiben, arccosine için iyi bir yaklaşım bulmamız gerekir. Tembel olduğum ve matematikte o kadar iyi olmadığım için, açıkça onu kaba kuvvet uygulayacağız.

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.

Jeneratör çözünürlüğü için çok sayıda kullanmış olabiliriz, manuel testin 7!makul derecede hızlı olmasına rağmen yeterince büyük olduğunu gösterdi .

Radyan olarak girdi alır, etrafındaki sayıları çıkarır.

Oliver sayesinde beş bayt tıraş oldu .

Çevrimiçi deneyin!


Sen kaldırabilirsiniz (in Mc(X-V. Char-kodu 1737ISO-8859-1 olmadığından, daha pahalı olan UTF-8'e geçer. Bunun yerine 173+ için karakter kodunu kullanabilirsiniz 7. ethproductions.github.io/japt/?v=1.4.5&code=I603&input=
Oliver

Ayrıca ,sonra ToMP:-) kaldırabilirsiniz
Oliver

@Oliver Çok teşekkürler, orijinal versiyonumda parantez gerekliydi, ancak biraz golf yaparken eskimişti, tamamen özledim. Ayrıca, kodlama şeyini bilmiyordum, bunun için de çok teşekkürler.
Nit

1
JavaScript yoluna gitmek istiyorsanız, her şeyi shoco üzerinden çalıştırabileceğinizi unutmayın.
Oliver



2

Jöle ,  23 22  18 bayt

Mil sayesinde -4 bayt ( formüllerini kullanırken {ve }kullanırken .

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

Sonucu döndüren (kayan nokta olarak) radyan cinsinden[ϕ1, ϕ2,] solda ve [λ1, λ2]sağda kabul eden ikili bir işlev .

Çevrimiçi deneyin!


Benim ... (ayrıca a kullanarak burada bir bayt kaydetti {)

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

Çevrimiçi deneyin


Çok ilginç, sayfayı tekrar yeniledim ve düzenlemenizi gösterdi, sadece değişikliği göstermek için yeni cevabı tıkladığınızda düzenlemelerinizi göstermek için güncellenmiyor. 18 bayt alternatifi;I}ÆẠP+ÆSP${ÆA×⁽£ġ
mil

Nasıl kullanılacağını asla anlamadım {ve }beklediğim şeyi asla yapmadılar. Bu, 17'de başka şekilde yapabileceğim anlamına gelmiyor mu ?!
Jonathan Allan

Olabilir. {ve }sadece bir monad'dan bir ikili yaratın. Benzer bir görüş olabilir P{ -> ḷP¥. Benzer durumlarda bir veya iki bayt kaydedebilen bir şey yapmak için hızlı bir kompozisyon (J'den) eklemek iyi x (P+$) y -> (P x) + (P y)olabilir.
mil

2

Eşleme Araç Kutulu MATLAB, 26 bayt

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

Meydan okumada açıklananla aynı sırayla, dört girişi hücre dizisi olarak alan anonim işlev.

Bunun kesin sonuçlar verdiğini unutmayın (Ay yarıçapının 1737 km olduğu varsayılarak), çünkü 1737/180eşittir 9.65.

Matlab R2017b'de çalışan örnek:

resim açıklamasını buraya girin


1

Python 3, 79 bayt

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

TIO'da geopy.py yok


2
@Nit, benim anlayışım, sorunun önünde halka açık bir kütüphane kullanmak adil bir oyun. MATLAB'ın harita araçlarını veya bir matematik kütüphanesi kullanan diğer dilleri kullanmak gibi olduğunu düşünüyorum.
RootTwo

1

APL (Dyalog Unicode) , 29 bayt SBCS

Programı tamamla. Stdin'i {ϕ₁, ϕ₂} sonra da {λ₁, λ₂} için soruyor. Stdout'a yazdırır.

R acos formülünü kullanır (sin ϕ₁ sin ϕ₂ + cos (λ₂ - λ₁) cos ϕ₁ cos ϕ₂)

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

Çevrimiçi deneyin! ( rfonksiyon dereceleri radyana dönüştürür)


 {ϕ₁, ϕ₂} istemi

1 2∘.○ Kartezyen tri-fonksiyon uygulaması; {{sin ϕ₁, sin ϕ₂}, {cos ϕ₁, cos ϕ₂}}

×/ sıralı ürünler; {sin ϕ₁ sin ϕ₂, cos ϕ₁ cos ϕ₂}

()×@2 İkinci öğede aşağıdakileri bununla çarpın:

 {λ₁, λ₂} istemi

-/ bunlar arasındaki fark; λ₁ - λ₂

2○ bunun kosinüsü; cos (λ₁ - λ₂)

Şimdi {sin ϕ₁ sin ϕ₂, cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂}

+/ Özetle; sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂

¯2○ bunun kosinüsü; cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂)

1737× r'yi bununla çarpın; 1737 cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂)


Derece olarak girişe izin veren fonksiyon:

○÷∘180

÷180 argüman bölü 180

 π ile çarp


1

C (gcc) , 100 88 65 64 bayt

88 → 65 @miles formülünü
kullanarak 65 → 64 @ Neil formülünü kullanarak

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

Çevrimiçi deneyin!


-lmDerleyici bayrağı için iki bayt eklemeniz gerektiğine inanıyorum .
OOBalance

@OOBalance: Bayrağın varlığı her zaman gerekli değildir. Derleyicinin sisteme nasıl yüklendiğine bağlıdır.
jxh

Peki. Sanırım bu benim bu cevap iki bayt çıkarabilir anlamına gelir: codegolf.stackexchange.com/a/161452/79343 Teşekkürler.
OOBalance

@OOBalance: Cevabı kaldırdı. Kendi çözümümü de sundum.
jxh

Güzel. Sizinkini de oyladınız.
OOBalance

1

Excel, 53 bayt

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

@ Neil'in formülünü kullanarak. Radyan cinsinden girdi.


1

Istakoz , 66 bayt

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

Miles'ın formülünü kullanır, ancak girdi derece cinsindendir. Bu, yarıçap ile çarpılmadan önce radyanlara dönüştürme için ek bir adım ekler.




1

SmileBASIC, 60 bayt

INPUT X,Y,S,T?1737*ACOS(COS(X-S)+COS(X)*COS(S)*(COS(T-Y)-1))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.