Yardım et okyanusta kayboldum!


11

Giriş

Bugün kano ile yalnız balığa gittim, maalesef uykuya daldım ve dere beni götürdü, küreklerimi kaybettim, şimdi gece ve okyanusta kayboldum! Sahili göremiyorum bu yüzden uzakta olmalıyım!

Cep telefonum var ama tuzlu su tarafından ıslandığı için arızalı, mikrofon ve telefon hoparlörü bozulduğu için hiçbir şey konuşamıyorum veya duyamıyorum, ancak sahilin plajındaki arkadaşına SMS gönderebilirim!

Arkadaşımın çok güçlü bir meşalesi var ve bana doğru yönü göstermek için bambonun köpeklerinin üstüne kaldırdı, ama kürek çekemediğim için kürek çekemiyorum, bu yüzden ona ne kadar uzak olduğumu söylemeliyim, beni yakala!

Arkadaşım, meşaleyi deniz seviyesinde 11.50 metrede tuttuğunu söyledi ve ışığı ufukta görebiliyorum. Şimdi okuldan sadece Dünya yarıçapının deniz seviyesinde 6371 Km olması gerektiğini hatırlıyorum ve kanomda oturuyorum, böylece gözlerimin de deniz seviyesinde olduğunu varsayabilirsiniz.

Görev

Akımlar beni her an hareket ettirdiğinden, arkadaşım meşaleyi zaman zaman yükseltiyor (şimdi 12.30 metrede), lütfen arkadaşımın konumundan mesafeyi hesaplamama yardımcı olacak tam bir program veya işlev yaz!

İşte bir diyagram (ölçekli değil):

resim açıklamasını buraya girin

Etiketli turuncu nokta Mbenim, etiketli kırmızı nokta Tmeşale. Yeşil çizgi Mve arasındaki doğrusal mesafedir.T

Giriş

Standart girişten torç yüksekliğini h, ufkun hemen üstünde gördüğüm deniz seviyesinde metre cinsinden, iki ondalık hassasiyetle (1 santimetre veya 0,01 metre hassasiyetle) kayan nokta sayısı şeklinde alın 0 ile 100 arasında değişir.

Çıktı

Yeşil çizginin öklid uzunluğunu 1 cm hassasiyetle döndürmelisiniz. Örneğin, metre cinsinden çıktı alırsanız, iki ondalık basamakla (en az) olmalıdır. Çıktı, metre veya kilometre olabilir, ancak doğruluğa saygı duyar.

Test senaryoları:

Tüm değerler metre cinsindendir.

11.5 > 12105.08
13.8 > 13260.45

kurallar

En kısa kod kazanır.


Sonuç matematiksel olarak doğru olmalı mı yoksa ilk 2 ondalık sayı uygunsa sorun yok mu? Yani hxh, 2xRxh ile karşılaştırıldığında küçüktür ve küçük mesafeler için ihmal edilebilir. (R, Dünya'nın yarıçapı ve h, torcun yüksekliğidir).
Osable

@ Metre cinsinden çıktı alırsanız ilk 2 ondalık sayıyı tamamlayın
Mario

Girdi aralığı nedir?
Osable

@Onable, girdinin 0 ila 100 arasında olduğunu düşünebilirsiniz (bu durumda gerekli / mümkün olandan çok daha fazla).
Mario

1
Sahil Güvenlik Yığın Borsası'nı denemeliydin - kod golferse okyanustan çıkmana yardımcı olamaz dostum!
corsiKa

Yanıtlar:


4

05AB1E ,13 12 10 bayt

Emigna sayesinde 2 bayt tasarruf etti.

OP'nin dünyanın yerel olarak bir düzlem olduğu varsayımı kullanılarak çağrılacak trigonometrik fonksiyonlar olmadığından, 05AB1E çözümü yapmak mümkün hale gelir.

•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

Çevrimiçi deneyin!


1
12742000yazılabilir•1#oC•
Emigna

Bilgi amaçlı olarak, 9 bayt olurdu: •1#oC•+*tin 2sable
Emigna

... temel 214 numarasını içeren bir dize tasvir ediyor mu? 05AB1E, bazen bu tür özel işlevler hakkında dokümantasyon eksikliği yaşıyor. Güzel 2sable cevap da. Birkaç gün önce öğrendim ama bu soru için kullanmayı düşünmedim.
Osable

Doğru. Bu, 214 numaralı tabanda kodlanmış bir temel 10 sayısıdır.
Emigna

Sonuç, trigonometri ile de elde edilebilir, ancak muhtemelen daha uzundur.
Mario

4

Python, 34 26 bayt:

( Osable sayesinde -8 bayt! )

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

Anonim bir lambda işlevi. Kilometre cinsinden girdi ve kilometre cinsinden çıktı alır. Olarak çağır print(<Function Name>(<Input>)).


lambda i:(i*(i+12742))**.5daha da kısa olurdu.
Osable

@Osable Güzel! Bunu yapmak üzereydim. :)
R. Kap

Matematiksel tolerans varsa ive 12742 arasındaki tutarsızlık göz önüne alındığında, ifade kısaltılabilir:(i*12742)**.5
Osable

Sonuçlar yanlış. 11,5m - ~ 12km yerine> ~ 380km
GB

@TR Program girdisini kilometre olarak okur.
Osable

4

PHP, 34 bayt

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

Yıkmak

   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

şimdiye kadar, bu eski Mathematica cevabı ile aynı

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

Şimdi, hepsi bu girişi eklemek için yapmak için sol =$argv[1]ve çıkışı <?=- bitmiş


4

dc, 16 11 bayt:

?d12742+*vp

Komut satırı üzerinden kilometre cinsinden giriş yapılmasını ister ve sonra kilometre cinsinden mesafeyi verir.

açıklama

?           # 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

Bu aşağıdakilerden yararlanır:

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

4

jq, 18 karakter

(12742e3+.)*.|sqrt

Yine aynı formülün başka bir kopyası.

Örnek çalışma:

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

Çevrimiçi test


4

Haskell, 22 bayt

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

Kullanımı:

Prelude> d 11.5
12105.087040166212

Pointfree: (23 bayt)

sqrt.((*)=<<(+12742e3))

3

R, 29 bayt

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

Stdin'den girdi alır


Birkaç bayt daha kısadır (h=scan())*(1+12742e3/h)^.5.
Flounderer

2

Mathematica, 16 bayt

Bunların her ikisi de kilometre cinsinden hem girdi hem de çıktı için çalışır:

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

Bu Pisagor'un soruna basit bir uygulamasıdır:

   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)

2

Jelly, Jelly'in kod sayfasında 9 bayt

Programı golf dilinde yazmaya karar verdim. Aslında diğer insanların kullandığı algoritmadan daha etkili bir algoritma buldum (en azından sorudaki gibi kısa mesafelerde), ancak Jelly'in sıkıştıramayacağı gerçek bir kayan nokta sayısı gerektirir, bu yüzden Pisagor bu.

+“Ȯịż’×µ½

Açıklama:

 “Ȯịż’     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

µAyırıcıya ihtiyacım var, ama bence kaçınılmaz; Jelly, komutların çoğunun ihtiyaç duyduğu argümanları tahmin edebilmek için 05AB1E üzerinde bir bayt kaydetti, ancak bu durumda sonuna kadar doğru tahmin edemez, bu yüzden bir ipucu vermeliydim.

Jelly, Jelly'in kod sayfasında 7 bayt

דȮịż’½

Diğer cevabımda açıkladığım gibi , Pisagor yaklaşımına seri yaklaşımı aslında soruda yer alan uzunluklar üzerinde daha iyi sonuçlar üretiyor (en azından örnek çıktılara daha yakın) ve daha kısa bir formüle sahip. Ben yazarken, 12742000'in karekökünü önceden hesaplamak yerine, önce 12742000 ile, sonra da aynı anda karekök ile çarpabileceğimi fark ettim. Bu, temel olarak ilave olmadan diğer formüle eşdeğerdir ve bu nedenle, ilave programdan çıkarılarak önceki programdan üretilebilir. Bu, iki bayt tasarrufu sağlıyor, çünkü şimdi açık bir şekilde ayrışıyor ve bu yüzden artık ihtiyacımız yok µ.


Bu optimizasyonu kullanmamaya karar verdim, çünkü h aralığı göz önüne alındığında santimetreye (cf. istenen çıktı) bakarsanız aynı değerleri vermez. Ayrıca 05AB1E'de 2 bayt tasarruf eder.
Osable

Optimizasyon ile 12105.081577585506 ve 13260.452480967608 çıktıları alıyorum; bunlar test senaryosunun çıktısına çok yakın ve yuvarlanıyor. Olmadan, daha uzak olan 12105.087040166212 ve 13260.459661716106'yı alırım (ve santimetre cinsinden yanlıştır, 13260.46'ya yuvarlanır). Diğer cevapta belirtildiği gibi, optimizasyon, optimize edilen koddan doğru değere daha yakın olur, çünkü onu iptal edecek hiçbir şeyi olmayan biri yerine birbirini büyük ölçüde iptal eden iki hata içerir.

İnceleme sırasında "Açık bırak" a oy verdiğiniz için, yorumlarda açıklama istediğim soruların yanıtlarını bildiğinizi düşündüğünüzü varsayıyorum. Bu nedenle lütfen soruyu açık bir şekilde düzenleyin.
Peter Taylor

1
Soru açık: yazarın gezinmeye yardımcı olması için arkadaşına olan mesafeyi bilmesi gerekiyor. Meşalenin konumunu 0.1 metrelik bir hassasiyetle belirleyebilir (bunu anlatılan hikayeden belirleyebiliriz). Bu kaçınılmaz olarak mevcut mesafedeki çıktıdan yaklaşık 1 metre belirsizlik verecektir (not: yazar etrafta sürükleniyor, bu nedenle çok hızlı bir şekilde hareket etmesi olası değil…) ve bu nedenle yaklaşık olarak doğru olan her şeyin kabul edilebilir. Sorunun bir kısmı, bu durumda ne kadar doğru olmanız gerektiğini belirlemektir!

1
İstenen çıktı, metre cinsinden 2 ondalık sayı gösterir. Dolayısıyla hassasiyetin 1 santimetre olması bekleniyor. Soruya yapılan yorumlarda OP, h'nin 100'e kadar çıkabileceğini söyledi. H = 100 ile orijinal algoritmadan 14 santimetre tutarsızlık var.
Osable

2

Ruby, 23

23 bayt, Km cinsinden

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

25 bayt, m olarak

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

1

Tcl, 49 bayt:

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

Peki, ben Tcl yepyeni, bu yüzden bu aşağı golf için herhangi bir ipucu çok takdir edilmektedir. Diğer cevaplarım gibi, kilometre cinsinden komut satırı girişi ve kilometre cinsinden çıktılar ister. Esasen mevcut dcve pythoncevaplarımın bir Tcl uyarlaması .


Bir yoktur ler olsun eksik ler
sergiol

1

x86_64 + SSE makine kodu, 16 bayt

Programın baytları solda (onaltılı olarak), sağda okumayı biraz daha kolay hale getirmek için bir sökme var. Bu, tek kesinlikli kayar nokta sayısı alan ve döndüren işlevler için normal x86_64 kuralını izleyen bir işlevdir (% xmm0 içindeki bağımsız değişkeni alır ve yanıtını aynı kayıt defterinde döndürür ve geçici olarak% xmm1 ve% eax kullanır; bunlar bir C programının kullanacağı aynı çağrı kurallarıdır ve bu nedenle işlevi doğrudan bir C programından çağırabilirsiniz, bu şekilde test ettim).

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

Yine de bir sökme işleminde bile bunun bir açıklaması gerekir. İlk olarak, formülü tartışmaya değer. Çoğu insan dünyanın eğriliğini görmezden geliyor ve mesafeyi ölçmek için Pisagor formülünü kullanıyor. Ben de yapıyorum ama seri genişleme yaklaşımı kullanıyorum; Sadece girdinin ilk gücü ile ilgili terimi alıyorum ve bu kısa mesafede çok küçük bir etkiye sahip olan üçüncü, beşinci, yedinci vb. Güçleri görmezden geliyorum. (Ayrıca, Pisagor yaklaşımı düşük bir değer verirken, seri genişlemesindeki sonraki terimler değeri azaltmaya hizmet ederken; bu nedenle, yaklaşık yanlış yönde itmeye yarayacak küçük bir faktörü göz ardı ederek, aslında daha az doğru bir formül kullanarak daha doğru bir sonuç elde edilir.) Formül √12742000 × √h;0x455f1980.

İnsanları karıştırabilecek bir sonraki şey, karekök ve çarpma için vektör talimatlarını neden kullanıyorum; %xmm0ve %xmm1her biri dört adet tek kesinlikli kayar nokta numarası tutabilir ve ben dörtünde de çalışıyorum. Buradaki mantık gerçekten basittir: kodlamaları, ilgili skaler talimatlardan bir bayt daha kısadır. Bu yüzden FPU'yu, tipik golf dili algoritmasından çok uzak olan bir yöntemde, kendimi iki bayt kurtarmak için bir dizi ekstra kare köklendirme ve sıfırlama yaparak yapabilirim. (Bir süre önce sohbet sırasında montajcıların golf dilini x86 derleyicisine çağırdım ve hala fikrimi değiştirmedim.)

Oradan, algoritma çok basit: %xmm1√12742000 üzerinden %eax(bayt cinsinden bellekten yüklenmekten daha kısa olan) yükleme, argümanın (ve üç sıfırın) karekökünü %xmm1ve %xmm0( ilk öğe hakkında), ardından geri dönün.


1

Minkolang v0.15, 22 bayt

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

Çevrimiçi deneyin!

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

1

JavaScript (ES6), 31 25 bayt

Değeri metre cinsinden görüntüler

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


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

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.