Bantu aku, aku tersesat di lautan!

11

pengantar

Hari ini saya pergi memancing sendirian dengan sampan, sayangnya saya tertidur dan arus membawa saya pergi, saya kehilangan dayung, sekarang malam dan saya tersesat di lautan! Saya tidak bisa melihat pantai jadi saya harus jauh!

Saya memiliki ponsel tetapi tidak berfungsi karena basah oleh air asin, saya tidak dapat berbicara atau mendengar apa pun karena mikrofon dan speaker ponsel rusak, tetapi saya dapat mengirim SMS ke teman saya yang berada di pantai pantai!

Teman saya memiliki obor yang sangat kuat dan dia mengangkatnya di atas tongkat bambu untuk menunjukkan kepada saya arah yang benar, tetapi saya tidak dapat mendayung karena saya tidak memiliki dayung, jadi saya harus mengatakan kepadanya seberapa jauh saya sehingga dia dapat mengirim seseorang ke tangkap aku!

Teman saya mengatakan kepada saya bahwa ia menjaga obor di ketinggian 11,50 meter di atas permukaan laut, dan saya bisa melihat cahaya tepat di cakrawala. Sekarang saya hanya ingat dari sekolah bahwa jari-jari Bumi seharusnya 6371 Km di permukaan laut, dan saya duduk di sampan saya sehingga Anda dapat berasumsi bahwa mata saya juga berada di permukaan laut.

Tugas

Karena arus menggerakkan saya dari waktu ke waktu, teman saya menaikkan obor dari waktu ke waktu (sekarang di ketinggian 12,30 meter), tolong tuliskan program atau fungsi lengkap yang akan membantu saya menghitung jarak dari posisi teman saya!

Berikut adalah diagram (bukan untuk skala):

masukkan deskripsi gambar di sini

Titik oranye berlabel Madalah saya, titik merah berlabel Tadalah obor. Garis hijau adalah jarak linear antara MdanT

Memasukkan

Ambil dari input standar ketinggian obor hdalam meter di permukaan laut, yang saya lihat tepat di atas cakrawala, dalam bentuk angka titik apung dengan presisi dua desimal (dengan akurasi 1 sentimeter atau 0,01 meter), di mulai dari 0 hingga 100.

Keluaran

Anda harus mengembalikan panjang garis hijau euclidean dengan akurasi 1 cm. Misalnya jika Anda menghasilkan dalam meter, harus dengan dua desimal (setidaknya). Outputnya bisa berupa meter atau kilometer, tetapi menghormati keakuratannya.

Kasus uji:

Semua nilai dalam meter.

11.5 > 12105.08
13.8 > 13260.45

Aturan

Kode terpendek menang.

Mario
sumber
Apakah hasilnya harus benar secara matematis atau apakah itu ok jika 2 desimal pertama ok? Maksud saya hxh kecil dibandingkan dengan 2xRxh dan dapat diabaikan untuk jarak kecil. (R adalah jari-jari Bumi dan h adalah ketinggian obor).
Osable
@ Desimal 2 desimal pertama dapat digunakan jika Anda menghasilkan meter
Mario
Berapa kisaran input?
Osable
@Osable Anda dapat mempertimbangkan input dari 0 hingga 100 (bahkan terlalu banyak dari yang diperlukan / mungkin dalam kasus ini)
Mario
1
Anda harus mencoba Coast Guard Stack Exchange - kode golferse tidak dapat membantu Anda keluar dari laut, man!
corsiKa

Jawaban:

4

05AB1E ,13 12 10 byte

Disimpan 2 byte berkat Emigna.

Karena tidak ada fungsi trigonometri yang dapat disebut dengan menggunakan asumsi OP bahwa bumi secara lokal adalah sebuah pesawat, menjadi mungkin untuk membuat solusi 05AB1E.

•1#oC•+¹*t

           For understanding purposes input is referred to as 'h'
•1#oC•     Push 12742000 [ = 2*R, where R is the radius of earth]
      +    Compute 2*R+h
       ¹*  Multiply by h. Result is (2*R*+h)*h
         t Take the square root of it and implicitly display it

Cobalah online!

Osable
sumber
1
12742000dapat ditulis sebagai•1#oC•
Emigna
Untuk referensi, itu akan menjadi 9 byte: •1#oC•+*tdalam 2sable
Emigna
Apakah string yang bersumber dari gambar menggambarkan ... nomor base 214? 05AB1E terkadang kekurangan dokumentasi tentang fungsi khusus tersebut. Jawaban 2sable bagus juga. Saya mengetahuinya beberapa hari yang lalu tetapi saya tidak berpikir untuk menggunakannya untuk pertanyaan ini.
Osable
Benar. Ini adalah nomor basis 10 yang disandikan dalam basis 214.
Emigna
Hasilnya dapat dicapai juga dengan trigonometri tetapi mungkin lebih lama.
Mario
4

Python, 34 26 byte:

( -8 byte terima kasih kepada Osable! )

lambda i:(i*(i+12742))**.5

Fungsi lambda anonim. Mengambil input dalam kilometer dan menghasilkan dalam kilometer. Diminta sebagai print(<Function Name>(<Input>)).

R. Kap
sumber
lambda i:(i*(i+12742))**.5akan lebih pendek.
Osable
@ Dapat Digunakan Bagus! Saya baru saja akan melakukan itu. :)
R. Kap
Jika ada toleransi matematis, mengingat perbedaan antara idan 12742, ungkapan dapat disingkat jadi:(i*12742)**.5
Osable
Hasilnya salah. 11.5m -> ~ 380km bukannya ~ 12km
GB
@ GB Program membaca inputnya sebagai kilometer.
Osable
4

PHP, 34 byte

<?=sqrt((12742e3+$h=$argv[1])*$h);

kerusakan

   r^2+x^2=(r+h)^2      # Pythagoras base
   r^2+x^2=r^2+2rh+h^2  # right term distributed
       x^2=    2rh+h^2  # -r^2
       x =sqrt(2rh+h^2) # sqrt

sejauh ini, ini identik dengan jawaban Mathematica lama

sqrt(2*6371e3*$h+$h*$h) # to PHP
sqrt(14742e3*$h+$h+$h)  # constants combined
sqrt((14742e3+$h)*$h)   # conjugation to save a byte
((14742e3+$h)*$h)**.5   # same size

sekarang yang tersisa untuk dilakukan adalah menambahkan input =$argv[1]dan output <?=- selesai

Titus
sumber
4

dc, 16 11 byte:

?d12742+*vp

Meminta input melalui baris perintah dalam kilometer dan kemudian menampilkan jarak dalam kilometer.

Penjelasan

?           # Prompt for input
 d          # Duplicate the top-of-stack value
  12742     # Push 12,742 onto the stack
       +    # Pop the top 2 values of the stack and push their sum
        *   # Pop top 2 values of the stack and push their product
         v  # Pop the remaining value and push the square root
          p # Output the result to STDOUT

Ini memanfaatkan hal-hal berikut:

((6371+h)**2-6371**2)**.5 
=> ((6371**2+12742h+h**2)-6371**2)**0.5 
=> (h**2+12742h)**0.5 
=> (h*(h+12742))**0.5
R. Kap
sumber
4

jq, 18 karakter

(12742e3+.)*.|sqrt

Namun salinan lain dari formula yang sama.

Contoh dijalankan:

bash-4.3$ jq '(12742e3+.)*.|sqrt' <<< 11.5
12105.087040166212

Tes online

manatwork
sumber
4

Haskell, 22 byte

d h=sqrt$h*(h+12742e3)

Pemakaian:

Prelude> d 11.5
12105.087040166212

Pointfree: (23 byte)

sqrt.((*)=<<(+12742e3))
Laikoni
sumber
3

R, 29 byte

h=scan();sqrt(h^2+2*h*6371e3)

Mengambil input dari stdin

Billywob
sumber
Beberapa byte lebih pendek adalah (h=scan())*(1+12742e3/h)^.5.
Flounderer
2

Mathematica, 16 byte

Salah satu dari ini bekerja untuk input dan output dalam kilometer:

(12742#+#*#)^.5&
((12742+#)#)^.5&

Ini adalah aplikasi sederhana Pythagoras untuk masalah ini:

   x*x + R*R = (R+h)*(R+h)
=> x*x = (R+h)*(R+h) - R*R
       = R*R + 2*R*h + h*h - R*R
       = 2*R*h + h*h
=>   x = √(2*R*h + h*h)
Martin Ender
sumber
2

Jelly, 9 byte di halaman kode Jelly

Saya memutuskan untuk mulai menulis program dalam bahasa golf. Saya benar-benar menemukan algoritma yang lebih efisien daripada yang digunakan orang lain (setidaknya dalam jarak pendek seperti yang ada di pertanyaan), tetapi itu membutuhkan angka floating-point literal yang tampaknya tidak dapat dikompresi oleh Jelly, jadi Pythagoras ini.

+“Ȯịż’×µ½

Penjelasan:

 “Ȯịż’     12742000, compressed base-250
+          add to argument
      ×    multiply with original argument
       µ   separator to avoid what would otherwise be a parsing ambiguity
        ½  square root everything seen so far
           implicit output at EOF

Kebutuhan akan µpemisah membuatku kesal, tapi kupikir itu tidak bisa dihindari; Jelly telah menyimpan byte lebih dari 05AB1E dengan bisa menebak argumen apa yang dibutuhkan banyak perintah, tetapi dalam kasus ini tidak dapat menebak dengan benar sampai akhir, jadi saya perlu memberikan petunjuk.

Jelly, 7 byte di halaman kode Jelly

דȮịż’½

Seperti yang saya jelaskan di jawaban saya yang lain , aproksimasi deret terhadap aproksimasi Pythagoras benar-benar menghasilkan hasil yang lebih baik daripada panjang yang termasuk dalam pertanyaan (setidaknya, mereka lebih dekat dengan contoh output), dan juga memiliki formula yang lebih pendek. Ketika saya sedang menulisnya, saya menyadari bahwa alih-alih menghitung akar kuadrat dari 12742000 sebelumnya, saya bisa mengalikan angka dengan 12742000 terlebih dahulu, dan kemudian kuadrat akar keduanya pada saat yang sama. Ini pada dasarnya setara dengan formula lain tanpa tambahan, dan dengan demikian, dapat diproduksi dari program sebelumnya dengan menghapus tambahan dari itu. Ini menghemat dua byte, karena sekarang diurai secara ambigu dan jadi kita tidak perlu µlagi.

Komunitas
sumber
Saya memutuskan untuk tidak menggunakan optimasi ini karena tidak menghasilkan nilai yang sama jika Anda melihat sentimeter (lih. Output yang diminta) mengingat kisaran jam. Ini juga akan menghemat 2 byte di 05AB1E.
Osable
Dengan optimasi, saya mendapatkan output dari 12105.081577585506 dan 13260.452480967608; mereka sangat dekat dengan keluaran test case, dan bulat untuk mereka. Tanpa, saya mendapatkan 12105.087040166212 dan 13260.459661716106, yang lebih jauh (dan yang terakhir salah dalam sentimeter, membulatkan ke 13260.46). Seperti yang disebutkan dalam jawaban lain, optimasi terjadi lebih dekat ke nilai yang benar daripada kode yang dioptimalkan karena mengandung dua kesalahan yang sebagian besar membatalkan satu sama lain, bukan hanya satu yang tidak ada yang membatalkannya.
Karena Anda baru saja memilih untuk "Biarkan terbuka" dalam antrian ulasan, saya menganggap Anda yakin Anda tahu jawaban atas pertanyaan yang saya minta klarifikasi dalam komentar. Oleh karena itu harap edit pertanyaan sehingga tidak ambigu.
Peter Taylor
1
Pertanyaannya tidak ambigu: penulis perlu mengetahui jarak ke temannya untuk membantu navigasi. Dia dapat menentukan posisi obor dengan akurasi 0,1 meter (kita dapat menentukan ini dari cerita yang diceritakan). Ini pasti akan memberikan sekitar 1 meter ketidakpastian dari output pada jarak saat ini (catatan: penulis melayang-layang, sehingga tidak mungkin bergerak sangat jauh dengan sangat cepat ...), dan karena itu segala sesuatu yang kira-kira seakurat itu mungkin akan dapat diterima. Sebagian dari masalahnya adalah menentukan seberapa akurat Anda harus berada dalam situasi ini!
1
Output yang diminta menunjukkan 2 desimal dalam meter. Jadi akurasi diharapkan menjadi 1 sentimeter. Dalam komentar untuk pertanyaan itu, OP mengatakan bahwa h dapat mencapai 100. Dengan h = 100 ada perbedaan 14 sentimeter dari algoritma asli.
Osable
2

Ruby, 23

23 byte, dalam Km

->h{(h*h+h*12742)**0.5}

25 byte, dalam m

->h{(h*h+h*12742e3)**0.5}
GB
sumber
1

Tcl, 49 byte:

set A [get stdin];puts [expr ($A*($A+12742))**.5]

Yah, saya baru mengenal Tcl, jadi setiap tips untuk bermain golf ini sangat dihargai. Seperti jawaban saya yang lain, meminta input baris perintah dalam kilometer dan output dalam kilometer. Pada dasarnya sebuah adaptasi Tcl dari jawaban dcdan pythonjawaban saya.

R. Kap
sumber
ada s hilang pada get s
sergiol
1

x86_64 + kode mesin SSE, 16 byte

Bytes program ada di sebelah kiri (dalam heksadesimal), ada pembongkaran di sebelah kanan untuk membuatnya sedikit lebih mudah dibaca. Ini adalah fungsi yang mengikuti konvensi x86_64 normal untuk fungsi yang mengambil dan mengembalikan angka floating point presisi tunggal (ia mengambil argumen dalam% xmm0 dan mengembalikan jawabannya dalam register yang sama, dan menggunakan% xmm1 dan% eax sebagai temporaries; ini adalah konvensi pemanggilan yang sama yang akan digunakan oleh program C, dan dengan demikian Anda dapat memanggil fungsi langsung dari program C, yang merupakan cara saya mengujinya).

b8 80 19 5f 45          mov    $0x455f1980,%eax
66 0f 6e c8             movd   %eax,%xmm1
0f 51 c0                sqrtps %xmm0,%xmm0
0f 59 c1                mulps  %xmm1,%xmm0
c3                      retq

Meskipun dengan pembongkaran, ini masih membutuhkan penjelasan. Pertama, ada baiknya membahas formula. Kebanyakan orang mengabaikan lengkungan bumi dan menggunakan rumus Pythagoras untuk mengukur jarak. Saya melakukannya juga, tetapi saya menggunakan perkiraan ekspansi seri; Saya hanya mengambil istilah yang berkaitan dengan kekuatan input pertama, dan mengabaikan kekuatan ketiga, kelima, ketujuh, dll., Yang semuanya hanya memiliki pengaruh yang sangat kecil pada jarak pendek ini. (Selain itu, perkiraan Pythagoras memberikan nilai yang rendah, sedangkan istilah selanjutnya dalam ekspansi seri berfungsi untuk mengurangi nilai; dengan demikian, dengan mengabaikan faktor kecil yang akan berfungsi untuk mendorong perkiraan di arah yang salah, saya benar-benar mendapatkan hasil yang lebih akurat dengan menggunakan rumus yang kurang akurat.) Rumusnya ternyata 712742000 × √h;0x455f1980.

Hal berikutnya yang mungkin membingungkan orang adalah mengapa saya menggunakan instruksi vektor untuk akar kuadrat dan multiply; %xmm0dan %xmm1dapat masing-masing memegang empat angka floating point presisi tunggal, dan saya beroperasi pada keempatnya. Alasannya di sini sangat sederhana: pengkodeannya satu byte lebih pendek dari pada instruksi skalar yang sesuai. Jadi saya bisa membuat FPU melakukan banyak pekerjaan ekstra rooting persegi dan mengalikan nol untuk menyelamatkan diri saya dua byte, dalam metode yang sangat mirip dengan algoritma bahasa golf yang khas. (Saya menyebut assembler x86 bahasa golf assembler dalam obrolan beberapa waktu yang lalu, dan saya masih belum berubah pikiran tentang hal itu.)

Dari sana, algoritma ini sangat sederhana: memuat %xmm1dengan √12742000 via %eax(yang lebih pendek dalam hal byte daripada memuatnya dari memori), akar kuadrat argumen (dan tiga nol), gandakan elemen yang sesuai dari %xmm1dan %xmm0(kami hanya peduli tentang elemen pertama), lalu kembali.


sumber
1

Minkolang v0.15, 22 byte

ndd*$r'12742000'*+1MN.

Cobalah online!

n                               gets input in the form of a number
 dd                             duplicates it twice
   *                            multiplies 2 of the duplicates with each other
                                STACK: [h, h*h]
    $r                          swap top two stack values
                                STACK: [h*h, h]
      '12742000'*               push this number and multiply the original input by it
                                STACK: [h*h, h*12742000]
                 +1M            adds the two values and takes their square root
                                STACK: [sqrt(h*h+h*12742000)]
                    N.          output as a number and end program
pengguna41805
sumber
1

JavaScript (ES6), 31 25 byte

Menampilkan nilai dalam meter

//the actual code 
f=h=>(h*h+12742e3*h)**0.5


console.log(f(11.5));
console.log(f(13.8));

pengguna41805
sumber