Pomóż mi zgubiłem się w oceanie!

11

Wprowadzenie

Dzisiaj łowiłem samotnie z kajakiem, niestety zasnąłem i strumień mnie zabrał, zgubiłem wiosła, teraz jest noc i zagubiłem się w oceanie! Nie widzę wybrzeża, więc muszę być daleko!

Mam telefon komórkowy, ale działa nieprawidłowo, ponieważ zmoczył go słona woda, nie mogę nic mówić ani słyszeć, ponieważ mikrofon i głośnik telefonu są zepsute, ale mogę wysyłać SMS-y do mojego przyjaciela, który jest na plaży na wybrzeżu!

Mój przyjaciel ma bardzo mocną pochodnię i podniósł ją na bambusowe laski, aby wskazać mi właściwy kierunek, ale nie mogę wiosłować, ponieważ nie mam wiosła, więc muszę mu powiedzieć, jak daleko jestem, aby mógł wysłać kogoś na Złap mnie!

Mój przyjaciel powiedział mi, że trzyma pochodnię na wysokości 11,50 metra na poziomie morza i widzę światło tuż nad horyzontem. Teraz pamiętam tylko ze szkoły, że promień Ziemi powinien wynosić 6371 km na poziomie morza, i siedzę w czółnie, więc możesz założyć, że moje oczy też są na poziomie morza.

Zadanie

Ponieważ prądy poruszają mnie chwila po chwili, mój przyjaciel od czasu do czasu podnosi pochodnię (teraz ma 12,30 metra), proszę napisać pełny program lub funkcję, która pomoże mi obliczyć odległość od pozycji mojego przyjaciela!

Oto schemat (nie w skali):

wprowadź opis zdjęcia tutaj

Pomarańczowy punkt oznaczony jako Mja, czerwony punkt oznaczony Tjako pochodnia. Zielona linia to liniowa odległość między MiT

Wejście

Weź ze standardowego wejścia wysokość pochodni hw metrach na poziomie morza, którą widzę tuż nad horyzontem, w postaci liczby zmiennoprzecinkowej z dokładnością do dwóch miejsc po przecinku (z dokładnością do 1 centymetra lub 0,01 metra), w zawiera się w zakresie od 0 do 100.

Wynik

Powinieneś zwrócić euklidesową długość zielonej linii z dokładnością do 1 cm. Na przykład, jeśli wyprowadzasz dane w metrach, powinno być z co najmniej dwoma miejscami po przecinku. Wydajność może wynosić albo metry, albo kilometry, ale z zachowaniem dokładności.

Przypadki testowe:

Wszystkie wartości w metrach.

11.5 > 12105.08
13.8 > 13260.45

Zasady

Najkrótszy kod wygrywa.

Mario
źródło
Czy wynik musi być matematycznie poprawny, czy jest w porządku, jeśli pierwsze 2 miejsca po przecinku są prawidłowe? Mam na myśli, że hxh jest niewielki w porównaniu do 2xRxh i można go pominąć na małych odległościach. (R to promień Ziemi, a h to wysokość pochodni).
Osable
@ Dostępne pierwsze 2 miejsca po przecinku są w porządku, jeśli podajesz dane w metrach
Mario
Jaki jest zakres danych wejściowych?
Osable
@ Włącz, możesz uznać, że dane wejściowe wynoszą od 0 do 100 (w tym przypadku nawet za dużo / więcej niż to konieczne / możliwe).
Mario
1
Powinieneś był spróbować wymiany stosu straży przybrzeżnej - kod golfisty nie może pomóc ci wydostać się z oceanu, stary!
corsiKa

Odpowiedzi:

4

05AB1E ,13 12 10 bajtów

Zaoszczędź 2 bajty dzięki Emignie.

Ponieważ nie ma żadnych funkcji trygonometrycznych, które można by wywoływać przy założeniu OP, że Ziemia jest lokalnie płaszczyzną, możliwe jest wykonanie rozwiązania 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

Wypróbuj online!

Osable
źródło
1
12742000można zapisać jako•1#oC•
Emigna
Dla porównania byłoby to 9 bajtów: •1#oC•+*tw 2sable
Emigna
Czy ciąg otoczony przez ... przedstawia numer ... base 214? 05AB1E czasami cierpi na brak dokumentacji takich specjalnych funkcji. Ładna 2sable odpowiedź również. Dowiedziałem się o tym kilka dni temu, ale nie zastanawiałem się nad użyciem go do tego pytania.
Osable
Poprawny. Jest to podstawowa liczba 10 zakodowana w bazie 214.
Emigna
Wynik można również osiągnąć za pomocą trygonometrii, ale prawdopodobnie jest on dłuższy.
Mario
4

Python, 34 26 bajtów:

( -8 bajtów dzięki Osable! )

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

Anonimowa funkcja lambda. Pobiera dane wejściowe w kilometrach i dane wyjściowe w kilometrach. Wywołaj jako print(<Function Name>(<Input>)).

R. Kap
źródło
lambda i:(i*(i+12742))**.5byłby jeszcze krótszy.
Osable
@Osable Nice! Właśnie miałem to zrobić. :)
R.Kap
Jeśli istnieje matematyczna tolerancja, biorąc pod uwagę rozbieżność między ii 12742, wyrażenie można skrócić w następujący sposób:(i*12742)**.5
Osable
Wyniki są błędne. 11,5 m -> ~ 380 km zamiast ~ 12 km
GB
@GB Program odczytuje dane wejściowe jako kilometry.
Osable,
4

PHP, 34 bajty

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

awaria

   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

jak dotąd jest to identyczne ze starą odpowiedzią Mathematica

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

teraz pozostaje tylko dodać dane wejściowe =$argv[1]i wyjściowe <?=- gotowe

Tytus
źródło
4

dc, 16 11 bajtów:

?d12742+*vp

Monituje o wprowadzenie za pomocą wiersza poleceń w kilometrach, a następnie wyświetla odległość w kilometrach.

Wyjaśnienie

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

Wykorzystuje to następujące:

((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
źródło
4

jq, 18 znaków

(12742e3+.)*.|sqrt

Jeszcze jedna kopia tej samej formuły.

Przykładowy przebieg:

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

Test online

człowiek w pracy
źródło
4

Haskell, 22 bajty

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

Stosowanie:

Prelude> d 11.5
12105.087040166212

Pointfree: (23 bajty)

sqrt.((*)=<<(+12742e3))
Laikoni
źródło
3

R, 29 bajtów

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

Pobiera dane wejściowe ze standardowego wejścia

Billywob
źródło
Kilka bajtów mniej (h=scan())*(1+12742e3/h)^.5.
Flądrowiec
2

Mathematica, 16 bajtów

Każda z tych czynności dotyczy zarówno wejścia, jak i wyjścia w kilometrach:

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

Jest to prosta aplikacja Pitagorasa na problem:

   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
źródło
2

Galaretka, 9 bajtów na stronie kodowej Galaretki

Postanowiłem spróbować programu w języku golfowym. Znalazłem bardziej wydajny algorytm niż ten, którego używają inni ludzie (przynajmniej na krótkich odległościach, jak ten w pytaniu), ale wymaga on dosłownie liczb zmiennoprzecinkowych, których Jelly nie wydaje się być w stanie skompresować, więc Pitagoras to jest.

+“Ȯịż’×µ½

Wyjaśnienie:

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

Potrzeba µseparatora denerwuje mnie, ale myślę, że jest to nieuniknione; Galaretka już zapisała bajt ponad 05AB1E, ponieważ jest w stanie odgadnąć, jakich argumentów wymaga wiele poleceń, ale w tym przypadku nie może poprawnie odgadnąć do końca, więc musiałem dać mu podpowiedź.

Galaretka, 7 bajtów na stronie kodowej Galaretki

דȮịż’½

Jak wyjaśniłem w mojej innej odpowiedzi , aproksymacja serii do aproksymacji Pitagorasa faktycznie daje lepsze wyniki na długościach zawartych w pytaniu (przynajmniej są bliższe przykładowym wynikom), a także ma krótszą formułę. Pisząc to, zdałem sobie sprawę, że zamiast z góry obliczyć pierwiastek kwadratowy z 12742000, najpierw mogłem pomnożyć liczbę przez 12742000, a następnie pierwiastek kwadratowy jednocześnie. Jest to zasadniczo równoważne z inną formułą bez dodatku i jako takie można ją wytworzyć z poprzedniego programu, usuwając z niej dodatek. To oszczędza dwa bajty, ponieważ teraz analizuje jednoznacznie, więc nie potrzebujemy µwięcej.

Społeczność
źródło
Postanowiłem nie używać tej optymalizacji, ponieważ nie daje ona takich samych wartości, jeśli spojrzysz na centymetry (patrz żądana moc wyjściowa), biorąc pod uwagę zakres h. Zaoszczędziłby również 2 bajty w 05AB1E.
Osable,
Dzięki optymalizacji otrzymuję dane wyjściowe 12105.081577585506 i 13260.452480967608; są one bardzo zbliżone do danych wyjściowych przypadku testowego i są do nich okrągłe. Bez dostaję 12105.087040166212 i 13260.459661716106, które są dalej (a te ostatnie są niepoprawne w centymetrach, zaokrąglając do 13260.46). Jak wspomniano w drugiej odpowiedzi, optymalizacja okazuje się być bliższa poprawnej wartości niż zoptymalizowany kod, ponieważ zawiera dwa błędy, które w dużej mierze się znoszą, a nie tylko jeden, który nie ma nic, co by je anulowało.
Ponieważ właśnie zagłosowałeś na „Pozostaw otwarte” w kolejce recenzji, zakładam, że uważasz, że znasz odpowiedzi na pytania, na które poprosiłem o wyjaśnienia w komentarzach. Dlatego prosimy o edycję pytania, aby było jednoznaczne.
Peter Taylor,
1
Pytanie jest jednoznaczne: autor musi znać odległość do swojego przyjaciela, aby pomóc w nawigacji. Może określić pozycję pochodni z dokładnością do 0,1 metra (możemy to ustalić na podstawie opowiadanej historii). To nieuchronnie da w przybliżeniu 1 metr niepewności na wyjściu w bieżącej odległości (uwaga: autor dryfuje, więc jest mało prawdopodobne, aby poruszał się bardzo daleko bardzo szybko…), a zatem wszystko, co jest w przybliżeniu tak dokładne, prawdopodobnie będzie do przyjęcia. Część problemu polega na określeniu dokładności, z jaką musisz być w tej sytuacji!
1
Żądany wynik pokazuje 2 miejsca po przecinku w metrach. Oczekuje się, że dokładność wyniesie 1 centymetr. W komentarzach do pytania OP stwierdził, że h może wzrosnąć do 100. Przy h = 100 występuje rozbieżność 14 centymetrów od pierwotnego algorytmu.
Osable,
2

Ruby, 23 lata

23 bajty, w km

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

25 bajtów, wm

->h{(h*h+h*12742e3)**0.5}
GB
źródło
1

Tcl, 49 bajtów:

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

Cóż, jestem zupełnie nowy w Tcl, więc wszelkie wskazówki dotyczące gry w golfa są bardzo mile widziane. Podobnie jak moje inne odpowiedzi, monity o wprowadzenie wiersza poleceń w kilometrach i wyjście w kilometrach. Zasadniczo adaptacja Tcl moich istniejących dci pythonodpowiedzi.

R. Kap
źródło
Jest s brakujące na get s
sergiol
1

x86_64 + kod maszynowy SSE, 16 bajtów

Bajty programu znajdują się po lewej stronie (w systemie szesnastkowym), po prawej stronie znajduje się demontaż, aby ułatwić czytanie. Jest to funkcja zgodna z normalną konwencją x86_64 dla funkcji pobierających i zwracających liczby zmiennoprzecinkowe pojedynczej precyzji (pobiera argument w% xmm0 i zwraca swoją odpowiedź w tym samym rejestrze oraz używa% xmm1 i% eax jako tymczasowych; te są tymi samymi konwencjami wywoływania, których będzie używał program w języku C, i jako taki możesz wywołać funkcję bezpośrednio z programu w języku C, tak jak ją przetestowałem.

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

Jednak nawet przy demontażu nadal wymaga to wyjaśnienia. Po pierwsze warto omówić formułę. Większość ludzi ignoruje krzywiznę ziemi i używa wzoru Pitagorasa do pomiaru odległości. Też to robię, ale używam przybliżenia rozszerzenia serii; Przyjmuję tylko termin odnoszący się do pierwszej mocy wejściowej i ignoruję moce trzecie, piąte, siódme itd., Które mają bardzo niewielki wpływ na tym krótkim dystansie. (Poza tym przybliżenie Pitagorasa daje niską wartość, podczas gdy późniejsze terminy w rozszerzeniu serii służą do zmniejszenia wartości; jako takie, ignorując niewielki czynnik, który służyłby do popychania przybliżenia w niewłaściwym kierunku, faktycznie się zdarza dokładniejszy wynik przy użyciu mniej dokładnej formuły.) Formuła okazuje się √12742000 × √h;0x455f1980.

Następną rzeczą, która może mylić ludzi, jest to, dlaczego używam instrukcji wektorowych dla pierwiastka kwadratowego i mnożenia; %xmm0i %xmm1może pomieścić cztery liczby zmiennoprzecinkowe pojedynczej precyzji, i działam na wszystkich czterech. Rozumowanie tutaj jest bardzo proste: ich kodowanie jest o jeden bajt krótsze niż w odpowiednich instrukcjach skalarnych. Mogę więc zmusić FPU do wykonania dodatkowej pracy polegającej na rootowaniu i mnożeniu zer w celu zaoszczędzenia sobie dwóch bajtów, metodą bardzo przypominającą typowy algorytm języka golfowego. (Nazywałam asemblera x86 golfowym językiem asemblerów na czacie jakiś czas temu i nadal nie zmieniłam zdania).

Stamtąd algorytm jest bardzo prosty: ładuj %xmm1za pomocą √12742000 przez %eax(który jest krótszy pod względem bajtów niż ładowanie go z pamięci), pierwiastek kwadratowy z argumentem (i trzema zerami), pomnóż odpowiednie elementy %xmm1i %xmm0(zależy nam tylko o pierwszym elemencie), a następnie wróć.


źródło
1

Minkolang v0.15, 22 bajty

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

Wypróbuj 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
user41805
źródło
1

JavaScript (ES6), 31 25 bajtów

Wyświetla wartość w metrach

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


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

user41805
źródło