Hilf mir, ich bin im Ozean verloren!

11

Einführung

Heute bin ich alleine mit meinem Kanu angeln gegangen, leider bin ich eingeschlafen und der Bach hat mich weggebracht, ich habe meine Ruder verloren, jetzt ist es Nacht und ich bin im Meer verloren! Ich kann die Küste nicht sehen, also muss ich weit weg sein!

Ich habe mein Handy, aber es funktioniert nicht, weil es durch das salzige Wasser nass geworden ist. Ich kann nichts sprechen oder hören, weil das Mikrofon und der Telefonlautsprecher kaputt sind, aber ich kann meinem Freund am Strand der Küste eine SMS senden!

Mein Freund hat eine sehr starke Fackel und er hat sie auf Bambusstangen gehoben, um mir die richtige Richtung zu zeigen, aber ich kann nicht rudern, weil ich keine Ruder habe, also muss ich ihm sagen, wie weit ich bin, damit er jemanden schicken kann Fang mich!

Mein Freund sagte mir, dass er die Fackel auf 11,50 Metern über dem Meeresspiegel hält und ich das Licht direkt über dem Horizont sehen kann. Jetzt erinnere ich mich nur noch an die Schule, dass der Erdradius 6371 km auf Meereshöhe betragen sollte, und ich sitze in meinem Kanu, sodass Sie davon ausgehen können, dass meine Augen auch auf Meereshöhe sind.

Aufgabe

Da mich die Strömungen von Moment zu Moment bewegen, hebt mein Freund von Zeit zu Zeit die Fackel an (jetzt sind es 12,30 Meter). Bitte schreiben Sie ein vollständiges Programm oder eine Funktion, mit deren Hilfe ich die Entfernung von der Position meines Freundes berechnen kann!

Hier ist ein Diagramm (nicht maßstabsgetreu):

Geben Sie hier die Bildbeschreibung ein

Der orangefarbene Punkt Mist ich, der rote Punkt Tist die Fackel. Die grüne Linie ist der lineare Abstand zwischen MundT

Eingang

Nehmen Sie von der Standardeingabe die Brennerhöhe hin Metern auf Meereshöhe, die ich direkt über dem Horizont sehe, in Form einer Gleitkommazahl mit einer Genauigkeit von zwei Dezimalstellen (mit einer Genauigkeit von 1 Zentimeter oder 0,01 Metern) in der Bereich von 0 bis 100 enthalten.

Ausgabe

Sie sollten die euklidische Länge der grünen Linie mit einer Genauigkeit von 1 cm zurückgeben. Wenn Sie beispielsweise in Metern ausgeben, sollte dies (mindestens) zwei Dezimalstellen sein. Die Ausgabe kann entweder Meter oder Kilometer sein, wobei die Genauigkeit zu beachten ist.

Testfälle:

Alle Werte in Metern.

11.5 > 12105.08
13.8 > 13260.45

Regeln

Der kürzeste Code gewinnt.

Mario
quelle
Muss das Ergebnis mathematisch korrekt sein oder ist es in Ordnung, wenn die ersten 2 Dezimalstellen in Ordnung sind? Ich meine, dass hxh im Vergleich zu 2xRxh klein ist und für kleine Entfernungen vernachlässigt werden kann. (R ist der Radius der Erde und h ist die Höhe der Fackel).
Osable
@Osable erste 2 Dezimalstellen sind in Ordnung, wenn Sie in Metern ausgeben
Mario
Was ist der Eingabebereich?
Osable
@Osable Sie können die Eingabe als von 0 bis 100 betrachten (in diesem Fall sogar zu viel als nötig / möglich).
Mario
1
Du hättest es mit dem Coast Guard Stack Exchange versuchen sollen - Code Golferse kann dir nicht helfen, aus dem Meer herauszukommen, Mann!
CorsiKa

Antworten:

4

05AB1E ,13 12 10 Bytes

2 Bytes dank Emigna gespeichert.

Da unter Verwendung der Annahme von OP, dass die Erde lokal eine Ebene ist, keine trigonometrischen Funktionen aufgerufen werden können, wird es möglich, eine 05AB1E-Lösung zu erstellen.

•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

Probieren Sie es online aus!

Osable
quelle
1
12742000kann geschrieben werden als•1#oC•
Emigna
Als Referenz wären es 9 Bytes gewesen: •1#oC•+*tin 2sable
Emigna
Stellt eine mit umgebende Zeichenfolge eine ... Basis 214-Zahl dar? 05AB1E leidet manchmal an einer Dokumentation zu solchen Sonderfunktionen. Schöne 2sable Antwort auch. Ich habe es vor ein paar Tagen herausgefunden, aber ich habe nicht darüber nachgedacht, es für diese Frage zu verwenden.
Osable
Richtig. Es ist eine Basis-10-Nummer, die in Basis 214 codiert ist.
Emigna
Das Ergebnis kann auch durch Trigonometrie erzielt werden, ist aber wahrscheinlich länger.
Mario
4

Python, 34 26 Bytes:

( -8 Bytes dank Osable! )

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

Eine anonyme Lambda-Funktion. Nimmt Eingaben in Kilometern und Ausgaben in Kilometern vor. Rufen Sie als auf print(<Function Name>(<Input>)).

R. Kap
quelle
lambda i:(i*(i+12742))**.5wäre noch kürzer.
Osable
@Osable Schön! Ich wollte das gerade tun. :)
R. Kap
Wenn es eine mathematische Toleranz igibt, kann der Ausdruck angesichts der Diskrepanz zwischen und 12742 so verkürzt werden:(i*12742)**.5
Osable
Ergebnisse sind falsch. 11,5 m -> ~ 380 km statt ~ 12 km
GB
@GB Das Programm liest seine Eingabe als Kilometer.
Osable
4

PHP, 34 Bytes

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

Nervenzusammenbruch

   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

Bisher ist dies identisch mit der alten Mathematica-Antwort

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

Jetzt müssen Sie nur noch Input =$argv[1]und Output hinzufügen <?=- fertig

Titus
quelle
4

Gleichstrom, 16 11 Bytes:

?d12742+*vp

Fordert zur Eingabe über die Befehlszeile in Kilometern auf und gibt dann die Entfernung in Kilometern aus.

Erläuterung

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

Dies nutzt Folgendes:

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

jq, 18 Zeichen

(12742e3+.)*.|sqrt

Noch eine Kopie derselben Formel.

Probelauf:

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

Online-Test

Mann bei der Arbeit
quelle
4

Haskell, 22 Bytes

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

Verwendung:

Prelude> d 11.5
12105.087040166212

Punktfrei: (23 Bytes)

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

R, 29 Bytes

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

Nimmt Eingaben von stdin entgegen

Billywob
quelle
Ein paar Bytes kürzer ist (h=scan())*(1+12742e3/h)^.5.
Flounderer
2

Mathematica, 16 Bytes

Beides funktioniert sowohl für die Eingabe als auch für die Ausgabe in Kilometern:

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

Dies ist eine einfache Anwendung von Pythagoras auf das 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
quelle
2

Jelly, 9 Bytes in Jellys Codepage

Ich beschloss, das Programm in einer Golfsprache zu schreiben. Ich habe tatsächlich einen effizienteren Algorithmus gefunden als den, den andere Leute verwenden (zumindest über kurze Entfernungen wie den in der Frage), aber er erfordert wörtliche Gleitkommazahlen, die Jelly nicht zu komprimieren scheint, also Pythagoras es ist.

+“Ȯịż’×µ½

Erläuterung:

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

Die Notwendigkeit des µTrennzeichens ärgert mich, aber ich denke, es ist unvermeidlich; Jelly hat bereits ein Byte über 05AB1E gespeichert, indem es erraten konnte, welche Argumente viele der Befehle benötigen, aber in diesem Fall kann es nicht bis zum Ende richtig erraten, daher musste ich ihm einen Hinweis geben.

Jelly, 7 Bytes in Jellys Codepage

דȮịż’½

Wie ich in meiner anderen Antwort erklärt habe , liefert die Seriennäherung an die Pythagoras-Näherung tatsächlich bessere Ergebnisse über die in der Frage enthaltenen Längen (zumindest sind sie näher an den Beispielausgaben) und hat auch eine kürzere Formel. Während ich es schrieb, wurde mir klar, dass ich, anstatt die Quadratwurzel von 12742000 im Voraus zu berechnen, zuerst die Zahl mit 12742000 und dann beide gleichzeitig mit der Quadratwurzel multiplizieren konnte. Dies entspricht im Wesentlichen der anderen Formel ohne den Zusatz und kann als solcher aus dem vorherigen Programm erzeugt werden, indem der Zusatz daraus entfernt wird. Dies spart zwei Bytes, da es jetzt eindeutig analysiert wird und wir keine mehr benötigen µ.

Gemeinschaft
quelle
Ich habe mich entschieden, diese Optimierung nicht zu verwenden, da sie bei Betrachtung der Zentimeter (vgl. Angeforderte Ausgabe) angesichts des Bereichs von h nicht die gleichen Werte liefert. Es würde auch 2 Bytes in 05AB1E sparen.
Osable
Mit der Optimierung erhalte ich Ausgaben von 12105.081577585506 und 13260.452480967608; Diese liegen sehr nahe an der Ausgabe des Testfalls und runden sie ab. Ohne erhalte ich 12105.087040166212 und 13260.459661716106, die weiter entfernt sind (und letzteres ist in Zentimetern falsch und auf 13260,46 gerundet). Wie in der anderen Antwort erwähnt, liegt die Optimierung näher am korrekten Wert als der optimierte Code, da sie zwei Fehler enthält, die sich weitgehend gegenseitig aufheben, und nicht nur einen, der nichts zum Aufheben hat.
Da Sie gerade in der Überprüfungswarteschlange für "Offen lassen" gestimmt haben, gehe ich davon aus, dass Sie die Antworten auf die Fragen kennen, für die ich in den Kommentaren um Klärung gebeten habe. Bitte bearbeiten Sie die Frage daher so, dass sie eindeutig ist.
Peter Taylor
1
Die Frage ist eindeutig: Der Autor muss die Entfernung zu seinem Freund kennen, um die Navigation zu erleichtern. Er kann die Position der Fackel mit einer Genauigkeit von 0,1 Metern bestimmen (wir können dies anhand der Geschichte bestimmen, die erzählt wird). Dies führt zwangsläufig zu einer Unsicherheit von ungefähr 1 Meter bei der Ausgabe in der aktuellen Entfernung (Hinweis: Der Autor driftet herum, daher ist es unwahrscheinlich, dass er sich sehr schnell sehr weit bewegt…), und daher ist alles, was ungefähr so ​​genau ist, wahrscheinlich akzeptabel. Ein Teil des Problems besteht darin, festzustellen, wie genau Sie in dieser Situation sein müssen!
1
Die angeforderte Ausgabe zeigt 2 Dezimalstellen in Metern. Die Genauigkeit wird also voraussichtlich 1 Zentimeter betragen. In den Kommentaren zur Frage sagte OP, dass h auf 100 steigen könnte. Mit h = 100 gibt es eine Abweichung von 14 Zentimetern vom ursprünglichen Algorithmus.
Osable
2

Ruby, 23

23 Bytes in km

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

25 Bytes in m

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

Tcl, 49 Bytes:

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

Nun, ich bin brandneu bei Tcl, daher sind alle Tipps zum Golfen sehr willkommen. Fordert wie meine anderen Antworten zur Eingabe der Befehlszeile in Kilometern und der Ausgabe in Kilometern auf. Im Wesentlichen eine Tcl-Anpassung meiner bestehenden dcund pythonAntworten.

R. Kap
quelle
es fehlt ein s auf get s
sergiol
1

x86_64 + SSE-Maschinencode, 16 Byte

Die Bytes des Programms befinden sich links (hexadezimal). Rechts befindet sich eine Demontage, um das Lesen zu erleichtern. Dies ist eine Funktion, die der normalen x86_64-Konvention für Funktionen folgt, die eine Gleitkommazahl mit einfacher Genauigkeit annehmen und zurückgeben (sie nimmt das Argument in% xmm0 und gibt seine Antwort im selben Register zurück und verwendet% xmm1 und% eax als temporäre Werte; diese sind die gleichen Aufrufkonventionen, die ein C-Programm verwendet, und als solche können Sie die Funktion direkt von einem C-Programm aus aufrufen (so habe ich sie getestet).

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

Auch bei einer Demontage bedarf dies noch einer Erklärung. Zunächst lohnt es sich, die Formel zu diskutieren. Die meisten Menschen ignorieren die Krümmung der Erde und verwenden die Pythagoras-Formel, um die Entfernung zu messen. Ich mache es auch, aber ich benutze eine Serienerweiterungsnäherung; Ich nehme nur den Begriff, der sich auf die erste Potenz des Eingangs bezieht, und ignoriere die dritte, fünfte, siebte Potenz usw., die alle auf dieser kurzen Distanz nur einen sehr geringen Einfluss haben. (Außerdem ergibt die Pythagoras-Näherung einen niedrigen Wert, während die späteren Terme in der Reihenerweiterung dazu dienen, den Wert zu verringern. Wenn ich also einen kleinen Faktor ignoriere, der dazu dienen würde, die Näherung in die falsche Richtung zu verschieben, bekomme ich tatsächlich ein genaueres Ergebnis durch Verwendung einer weniger genauen Formel.) Die Formel lautet √12742000 × √h;0x455f1980.

Das nächste, was die Leute verwirren könnte, ist, warum ich Vektoranweisungen für die Quadratwurzel und die Multiplikation verwende. %xmm0und %xmm1kann jeweils vier Gleitkommazahlen mit einfacher Genauigkeit enthalten, und ich arbeite mit allen vier. Die Argumentation hier ist wirklich einfach: Ihre Codierung ist ein Byte kürzer als die der entsprechenden skalaren Anweisungen. So kann ich die FPU dazu bringen, eine Menge zusätzlicher Arbeit mit Quadratwurzeln und Multiplizieren von Nullen zu erledigen, um mir zwei Bytes zu ersparen, eine Methode, die sehr an den typischen Algorithmus der Golfsprache erinnert. (Ich habe x86 Assembler vor einiger Zeit die Golfsprache von Assemblern im Chat genannt, und ich habe meine Meinung dazu noch nicht geändert.)

Von dort aus ist der Algorithmus sehr einfach: Laden %xmm1mit √12742000 via %eax(was in Bezug auf Bytes kürzer ist als das Laden aus dem Speicher), Quadratwurzel des Arguments (und drei Nullen), Multiplizieren der entsprechenden Elemente von %xmm1und %xmm0(wir kümmern uns nur darum über das erste Element), dann zurück.


quelle
1

Minkolang v0.15, 22 Bytes

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

Probieren Sie es online aus!

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
quelle
1

JavaScript (ES6), 31 25 Byte

Zeigt den Wert in Metern an

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


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

user41805
quelle