Jarak antara dua titik di Bulan


11

Diberikan lintang / bujur dua titik di Bulan (lat1, lon1)dan (lat2, lon2), hitung jarak antara dua titik dalam kilometer, dengan menggunakan rumus apa pun yang memberikan hasil yang sama dengan rumus haversine.

Memasukkan

  • Empat nilai integer lat1, lon1, lat2, lon2dalam derajat (sudut) atau
  • empat nilai desimal ϕ1, λ1, ϕ2, λ2dalam radian.

Keluaran

Jarak dalam kilometer antara dua titik (desimal dengan presisi atau bilangan bulat bulat).

Formula Haversine

d = 2 r \ arcsin \ kiri (\ sqrt {\ sin ^ 2 \ kiri (\ frac {\ phi_2 - \ phi_1} {2} \ kanan) + \ cos (\ phi_1) \ cos (\ phi_2) \ sin ^ 2 \ kiri (\ frac {\ lambda_2 - \ lambda_1} {2} \ kanan)} \ kanan)

dimana

  • r adalah jari-jari bola (anggap jari-jari Bulan adalah 1.737 km),
  • ϕ1 lintang titik 1 dalam radian
  • ϕ2 lintang titik 2 dalam radian
  • λ1 bujur titik 1 dalam radian
  • λ2 bujur titik 2 dalam radian
  • d adalah jarak melingkar antara dua titik

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

Formula lain yang mungkin

  • d = r * acos(sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1)) @miles rumus ' .
  • d = r * acos(cos(ϕ1 - ϕ2) + cos ϕ1 cos ϕ2 (cos(λ2 - λ1) - 1)) @Neil formula .

Contoh di mana input adalah derajat dan output sebagai integer bulat

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

Aturan

  • Input dan output dapat diberikan dalam format apa pun yang nyaman .
  • Tentukan dalam jawaban apakah input dalam derajat atau radian .
  • Tidak perlu menangani nilai lintang / bujur yang tidak valid
  • Program lengkap atau fungsi dapat diterima. Jika suatu fungsi, Anda dapat mengembalikan output daripada mencetaknya.
  • Jika memungkinkan, harap sertakan tautan ke lingkungan pengujian online sehingga orang lain dapat mencoba kode Anda!
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.

7
Menggunakan formula khusus itu adalah persyaratan yang tidak dapat diobservasi. Apakah tidak cukup untuk memberikan hasil yang sama dengan formula itu ?
Adám

1
Bisakah kita mengambil input dalam radian?
Adám

1
@ mdahmoune OK, jadi Anda terdaftar dalam derajat untuk kemudahan menulis, tetapi mungkin kami memerlukan input untuk menjadi radian? Kalau tidak, tantangan ini menjadi kombinasi (yang buruk) dari konversi sudut dan tantangan utama.
Adám

5
Saya telah menurunkan pertanyaan ini karena sepertinya lebih menjadi 'Bahasa siapa yang paling bisa bermain golf formula ini', yang, menurut saya, tidak terlalu menarik.
caird coinheringaahing

2
Formula yang lebih pendek untuk sebagian besar bahasa adalah di d = r * acos( sin ϕ1 sin ϕ2 + cos ϕ1 cos ϕ2 cos(λ2 - λ1) )manar = 1737
miles

Jawaban:



6

R + geosphere , 54 47 bytes

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

Cobalah online!

Mengambil input sebagai vektor 2-elemen longitude,latitudedalam derajat. TIO tidak memiliki geospherepaket tetapi yakinlah bahwa ia mengembalikan hasil yang identik dengan fungsi di bawah ini.

Terima kasih kepada Jonathan Allan karena telah memangkas 7 byte.

R , 64 byte

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

Cobalah online!

Mengambil 4 input seperti dalam kasus uji, tetapi dalam radian bukan derajat.


Apakah e3dan /1000benar-benar diperlukan?
Jonathan Allan

1
@ Jonathan, Allan tidak, mereka tidak. Itu cukup bodoh dari saya, tetapi argumen default untuk jari-jari adalah bumi dalam meter sehingga logis pada saat itu, lol
Giuseppe

Perhatikan bahwa hukum bola cosinus tidak stabil secara numerik, khususnya untuk jarak kecil. Itu mungkin ok di Mathematica , tetapi dalam R dan sebagian besar bahasa lainnya masih bisa diperdebatkan apakah kriteria "formula apa pun yang memberikan hasil yang sama dengan rumus haversine" terpenuhi.
Berhenti menghidupkan counterclockwis

@ceasedtoturncounterclockwis saya sebagian besar memasukkannya demi memilikinya di basis R. Saya kira menggunakan perpustakaan floating point presisi sewenang-wenang akan mengurangi efek.
Giuseppe

Ya, atau menggunakan rumus stabil seperti, katakanlah, rumus haversine ...
berhenti mengubah counterclockwis


5

JavaScript (ES7), 90 byte

Catatan: lihat posting @ OlivierGrégoire untuk solusi yang jauh lebih pendek

Port langsung dari jawaban TFeld . Mengambil input dalam radian.

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

Cobalah online!

Menggunakan yang terkenal with(), 85 byte

Terima kasih kepada @ l4m2 untuk menghemat 6 byte

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

Cobalah online!


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

77 byte menggunakan algoritma pendek @miles ' :(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 byte menggunakan @ Neil 's algoritma yang lebih pendek :(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 byte mengoptimalkan jawaban semua orang:(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 Sangat bagus. Anda mungkin harus mempostingnya sebagai jawaban baru.
Arnauld

5

APL (Dyalog Unicode) , 40 35 byte SBCS

Fungsi diam-diam anonim. Membawa {ϕ₁, λ₁} sebagai argumen kiri dan {ϕ₂, λ₂} sebagai argumen benar.

Menggunakan rumus 2 r √ (sin² ( (ϕ₁-ϕ₂)2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂)2 ))

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

Cobalah online! ( rfungsi mengubah derajat ke radian)


 menggabungkan elemen yang sesuai; {{ϕ₁, ϕ₂}, {λ₁, λ₂}}

 pilih yang pertama; {ϕ₁, ϕ₂}

 kemudian

2×.○ produk dari cosinus mereka; cos ϕ₁ cos ϕ₂
menyala dot "produk" tetapi dengan selektor fungsi trigonometri (2 adalah cosinus) alih-alih perkalian dan kali bukan plus

1, tambahkan 1 untuk itu; {1, cos ϕ₁ cos ϕ₂}

(...  kalikan itu dengan hasil menerapkan fungsi berikut ke {ϕ₁, λ₁} dan {ϕ₂, λ₂}:

- perbedaan mereka; {ϕ₁ - ϕ₂, λ₁ - λ₂}

2÷⍨ bagi dengan 2; { (ϕ₁ - ϕ₂)2 , (λ₁ - λ₂)2 }

1○ sinus itu; {sin ( (ϕ₁ - ϕ₂)2 ), sin ( (λ₁ - λ₂)2 )}

×⍨ kuadrat itu (lit. memperbanyak diri); {sin² ( (ϕ₁ - ϕ₂)2 ), sin² ( (λ₁-λ₂)2 )}

Sekarang kita memiliki {sin² ( (ϕ₁ - ϕ₂)2 ), cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂)2 )}

1⊥ jumlah itu (lit. evaluasi dalam basis-1); sin² ( (ϕ₁-ϕ₂)2 ) + cos ϕ₁ cos ϕ₂ sin² ( (λ₁ - λ₂)2 )

.5*⍨ akar kuadrat itu (lit. naikkan itu ke kekuatan setengah)

¯1○ arcsine itu

3474× kalikan dengan ini


Fungsi untuk memungkinkan input dalam derajat adalah:

○÷∘180

÷180 argumen dibagi 180

 kalikan dengan π


4

Python 2 , 95 byte

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*

Cobalah online!

Mengambil input dalam radian.


Versi lama, sebelum i / o kendor: Mengambil input sebagai derajat bilangan bulat, dan mengembalikan dist bulat

Python 2 , 135 byte

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

Cobalah online!


Anda dapat menjatuhkan intdan roundkarena desimal diizinkan sebagai output, Anda juga dapat menghindari konversi ke radian karena input sebagai radian juga diperbolehkan
mdahmoune

@mdahmoune, Terima kasih, diperbarui
TFeld

3

Java 8, 113 92 88 82 byte

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

Input a,b,c,dyang ϕ1,λ1,ϕ2,λ2dalam radian.

-21 byte menggunakan formula pendek @miles .
-4 byte berkat @ OlivierGrégore karena saya masih digunakan {Math m=null;return ...;}dengan setiap Math.sebagai m., bukan menjatuhkan returndan menggunakan Mathlangsung.
-6 byte menggunakan @ Neil rumus 's lebih pendek .

Cobalah online.

Penjelasan:

(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
"Optimalisasi prematur adalah akar dari semua kejahatan"! 88 byte:(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

" Optimalisasi prematur adalah akar dari semua kejahatan " Saya kira Anda memang benar .. Terima kasih!
Kevin Cruijssen

1
Saya telah menemukan formulasi yang lebih pendek:(a,b,c,d)->1737*Math.acos(Math.cos(a-c)+Math.cos(a)*Math.cos(c)*(Math.cos(d-b)-1))
Neil

(Formulasi itu tidak lebih pendek dalam Bahasa Wolfram asli.)
Neil

3

Japt , 55 50 byte

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

Tidak harus setepat jawaban yang lain, tetapi anak laki-laki saya bersenang-senang dengan yang satu ini. Izinkan saya untuk menjelaskan.
Sementara di sebagian besar bahasa, tantangan ini cukup mudah, Japt memiliki properti yang disayangkan bahwa tidak ada built-in untuk arcsine maupun arccosine. Tentu, Anda dapat menanamkan Javascript di Japt, tapi itu akan menjadi kebalikan dari Feng Shui.

Yang harus kita lakukan untuk mengatasi gangguan kecil ini hanyalah perkiraan arccosine dan kita baik-baik saja!

Bagian pertama adalah segala sesuatu yang dimasukkan ke dalam arccosine.

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.

Hasilnya secara implisit disimpan Uuntuk digunakan nanti.

Setelah itu, kita perlu menemukan perkiraan yang bagus untuk arccosine. Karena saya malas dan tidak pandai matematika, kami jelas hanya akan memaksakannya.

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.

Kami dapat menggunakan sejumlah besar untuk resolusi generator, pengujian manual menunjukkan 7!cukup besar sementara cukup cepat.

Mengambil input sebagai radian, menghasilkan angka yang tidak dikelilingi.

Dicukur lima byte berkat Oliver .

Cobalah online!


Anda dapat menghapus (di Mc(X-V. Karena char-code untuk 1737bukan ISO-8859-1, ia beralih ke UTF-8, yang harganya lebih mahal. Anda bisa menggunakan char-code untuk 173+ 7. ethproductions.github.io/japt/?v=1.4.5&code=I603&input=
Oliver

Anda juga dapat menghapus ,setelah ToMP:-)
Oliver

@ Lebih Banyak Terima kasih, tanda kurung diperlukan dalam versi asli saya tetapi menjadi usang ketika bermain golf sedikit, saya benar-benar melewatkannya. Juga, tidak tahu tentang hal encoding, terima kasih banyak untuk itu juga.
Nit

1
Jika Anda ingin pergi dengan rute JavaScript, perlu diingat bahwa Anda dapat menjalankan semuanya melalui shoco.
Oliver



2

Jelly ,  23 22  18 byte

-4 byte berkat mil (menggunakan {dan }saat menggunakan formula mereka .

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

Fungsi diadik yang menerima [ϕ1, ϕ2,]di sebelah kiri dan [λ1, λ2]di kanan dalam radian yang mengembalikan hasilnya (sebagai titik mengambang).

Cobalah online!


Milik saya ... (juga menyimpan satu byte di sini dengan menggunakan a {)

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

Cobalah online


Oh menarik, saya me-refresh halaman lagi dan itu menunjukkan hasil edit Anda, hanya mengklik jawaban baru untuk menunjukkan perubahan tidak memperbarui untuk menampilkan suntingan Anda. alternatif 18 byte adalah;I}ÆẠP+ÆSP${ÆA×⁽£ġ
mil

Tidak pernah mengerti cara menggunakan {dan }mereka tidak pernah melakukan apa yang saya harapkan. Bukankah itu berarti saya bisa melakukan sebaliknya di 17 ?!
Jonathan Allan

Mungkin. {dan }hanya membuat angka dua dari monad. Pandangan serupa mungkin P{ -> ḷP¥. Mungkin baik untuk menambahkan menulis (dari J) cepat untuk melakukan sesuatu seperti x (P+$) y -> (P x) + (P y)yang dapat menyimpan satu atau dua byte dalam situasi yang sama.
miles

2

MATLAB dengan Mapping Toolbox, 26 byte

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

Fungsi anonim yang mengambil empat input sebagai array sel, dalam urutan yang sama seperti yang dijelaskan dalam tantangan.

Perhatikan bahwa ini memberikan hasil yang tepat (dengan asumsi bahwa jari-jari Bulan adalah 1.737 km), karena 1737/180sama dengan 9.65.

Contoh dijalankan di Matlab R2017b:

masukkan deskripsi gambar di sini


1

Python 3, 79 byte

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

TIO tidak memiliki geopy.py


2
@Tidak, pemahaman saya adalah bahwa itu adalah permainan yang adil untuk menggunakan perpustakaan yang tersedia untuk umum yang mendahului pertanyaan. Saya pikir itu seperti menggunakan alat pemetaan MATLAB, atau bahasa lain menggunakan perpustakaan matematika.
RootTwo

1

APL (Dyalog Unicode) , 29 byte SBCS

Program lengkap. Anjurkan stdin untuk {ϕ₁, ϕ₂} dan kemudian untuk {λ₁, λ₂}. Mencetak ke stdout.

Menggunakan rumus r acos (sin ϕ₁ sin ϕ₂ + cos (λ₂ - λ₁) cos ϕ₁ cos ϕ₂)

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

Cobalah online! ( rfungsi mengubah derajat ke radian)


 prompt untuk {ϕ₁, ϕ₂}

1 2∘.○ Aplikasi fungsi trigonometri Cartesian; {{sin ϕ₁, sin ϕ₂}, {cos ϕ₁, cos ϕ₂}}

×/ produk bijaksana; {sin ϕ₁ sin ϕ₂, cos ϕ₁ cos ϕ₂}

(... )×@2 pada elemen kedua, gandakan yang berikut dengan itu:

 prompt untuk {λ₁, λ₂}

-/ perbedaan antara mereka; λ₁ - λ₂

2○ cosinus itu; cos (λ₁ - λ₂)

Sekarang kita memiliki {sin ϕ₁ sin ϕ₂, cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂}

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

¯2○ cosinus itu; cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂)

1737× kalikan r dengan itu; 1737 cos (sin ϕ₁ sin ϕ₂ + cos (λ₁ - λ₂) cos ϕ₁ cos ϕ₂)


Fungsi untuk memungkinkan input dalam derajat adalah:

○÷∘180

÷180 argumen dibagi 180

 kalikan dengan π


1

C (gcc) , 100 88 65 64 byte

88 → 65 menggunakan formula @miles '65
→ 64 menggunakan formula @ Neil

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

Cobalah online!


Saya yakin Anda perlu menambahkan dua byte untuk -lmflag compiler.
OOBalance

@OOBalance: Kehadiran bendera tidak selalu diperlukan. Itu tergantung pada bagaimana kompiler diinstal pada sistem.
jxh

Baik. Tebak ini berarti saya dapat mengurangi dua byte pada jawaban saya ini: codegolf.stackexchange.com/a/161452/79343 Terima kasih.
OOBalance

@OOBalance: Jawabannya dibalik. Saya juga mengirimkan solusi saya sendiri.
jxh

Bagus. Terbalik milikmu juga.
OOBalance

1

Excel, 53 byte

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

Menggunakan rumus @ Neil. Masukan dalam radian.


1

Lobster , 66 byte

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

Menggunakan rumus miles, tetapi input dalam derajat. Ini menambahkan langkah ekstra konversi ke radian sebelum dikalikan dengan jari-jari.




1

SmileBASIC, 60 byte

INPUT X,Y,S,T?1737*ACOS(COS(X-S)+COS(X)*COS(S)*(COS(T-Y)-1))
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.