Aidez-moi, je suis perdu dans l'océan!


11

introduction

Aujourd'hui je suis allé pêcher seul avec mon canoë, malheureusement je me suis endormi et le ruisseau m'a emporté, j'ai perdu mes rames, maintenant il fait nuit et je suis perdu dans l'océan! Je ne peux pas voir la côte donc je dois être loin!

J'ai mon téléphone portable mais est défectueux car il a été mouillé par l'eau salée, je ne peux pas parler ou entendre quoi que ce soit car le micro et le haut-parleur du téléphone sont cassés, mais je peux envoyer des SMS à mon ami qui est sur la plage de la côte!

Mon ami a une torche très puissante et il l'a soulevée au-dessus des cannes de bambou pour me montrer la bonne direction, mais je ne peux pas ramer parce que je n'ai pas de rames, donc je dois lui dire à quelle distance je suis pour qu'il puisse envoyer quelqu'un à attrapez-moi!

Mon ami m'a dit qu'il maintenait la torche à 11,50 mètres au niveau de la mer, et je peux voir la lumière juste à l'horizon. Maintenant, je me souviens seulement de l'école que le rayon de la Terre devrait être de 6371 km au niveau de la mer, et je suis assis dans mon canot afin que vous puissiez supposer que mes yeux sont également au niveau de la mer.

Tâche

Comme les courants me déplacent de moment en moment, mon ami lève la torche de temps en temps (maintenant il est à 12,30 mètres), veuillez écrire un programme ou une fonction complète qui m'aidera à calculer la distance de la position de mon ami!

Voici un schéma (pas à l'échelle):

entrez la description de l'image ici

Le point orange marqué Mest moi, le point rouge marqué Test la torche. La ligne verte est la distance linéaire entre MetT

Contribution

Prenez à partir de l'entrée standard la hauteur de la torche hen mètres au niveau de la mer, que je vois juste au-dessus de l'horizon, sous la forme d'un nombre à virgule flottante avec une précision de deux décimales (avec une précision de 1 centimètre ou 0,01 mètre), dans le gamme de 0 à 100 inclus.

Production

Vous devez renvoyer la longueur euclidienne de la ligne verte avec une précision de 1 cm. Par exemple, si vous produisez en mètres, cela devrait être avec deux décimales (au moins). La sortie peut être en mètres ou en kilomètres, mais en respectant la précision.

Cas de test:

Toutes les valeurs en mètres.

11.5 > 12105.08
13.8 > 13260.45

Règles

Le code le plus court gagne.


Le résultat doit-il être mathématiquement correct ou est-ce correct si les 2 premières décimales sont correctes? Je veux dire que hxh est petit par rapport à 2xRxh et peut être négligé pour de petites distances. (R est le rayon de la Terre et h est la hauteur de la torche).
Osable

@Osable Les 2 premières décimales sont correctes si vous produisez en mètres
Mario

Quelle est la plage d'entrée?
Osable

@Osable vous pouvez considérer l'entrée comme étant de 0 à 100 (même trop que nécessaire / possible dans ce cas).
Mario

1
Vous auriez dû essayer le Coast Guard Stack Exchange - le code golferse ne peut pas vous aider à sortir de l'océan, mec!
corsiKa

Réponses:


4

05AB1E ,13 12 10 octets

Enregistré 2 octets grâce à Emigna.

Puisqu'il n'y a pas de fonctions trigonométriques à appeler en utilisant l'hypothèse d'OP que la terre est localement un plan, il devient possible de faire une solution 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

Essayez-le en ligne!


1
12742000peut être écrit comme•1#oC•
Emigna

Pour référence, il aurait été de 9 octets: •1#oC•+*ten 2sable
Emigna

Est-ce qu'une chaîne entourée de représente un ... nombre 214 de base? 05AB1E souffre parfois d'un manque de documentation sur ces fonctions spéciales. Belle réponse 2sable aussi. Je l'ai découvert il y a quelques jours mais je n'ai pas pensé à l'utiliser pour cette question.
Osable

Correct. C'est un nombre de base 10 codé en base 214.
Emigna

Le résultat peut également être obtenu par trigonométrie mais est probablement plus long.
Mario

4

Python, 34 26 octets:

( -8 octets grâce à Osable! )

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

Une fonction lambda anonyme. Prend les entrées en kilomètres et les sorties en kilomètres. Invoquer en tant que print(<Function Name>(<Input>)).


lambda i:(i*(i+12742))**.5serait encore plus court.
Osable

@Osable Nice! J'étais sur le point de faire ça. :)
R. Kap

S'il y a une tolérance mathématique, étant donné l'écart entre iet 12742, l'expression peut être raccourcie ainsi:(i*12742)**.5
Osable

Les résultats sont faux. 11,5 m -> ~ 380 km au lieu de ~ 12 km
GB

@GB Le programme lit ses données en kilomètres.
Osable

4

PHP, 34 octets

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

panne

   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

jusqu'à présent, c'est identique à l'ancienne réponse 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

il ne reste plus qu'à ajouter des entrées =$argv[1]et des sorties <?=- c'est fait


4

dc, 16 11 octets:

?d12742+*vp

Demande l'entrée via la ligne de commande en kilomètres, puis affiche la distance en kilomètres.

Explication

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

Cela profite des avantages suivants:

((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 caractères

(12742e3+.)*.|sqrt

Encore une autre copie de la même formule.

Exemple d'exécution:

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

Test en ligne


4

Haskell, 22 octets

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

Usage:

Prelude> d 11.5
12105.087040166212

Sans point: (23 octets)

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

3

R, 29 octets

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

Prend l'entrée de stdin


Un couple d'octets plus court est (h=scan())*(1+12742e3/h)^.5.
Flounderer

2

Mathematica, 16 octets

L'un ou l'autre de ces travaux pour l'entrée et la sortie en kilomètres:

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

Il s'agit d'une simple application de Pythagore au problème:

   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, 9 octets dans la page de codes de Jelly

J'ai décidé d'essayer d'écrire le programme dans une langue de golf. J'ai en fait trouvé un algorithme plus efficace que celui que les autres utilisent (au moins sur de courtes distances comme celui de la question), mais il nécessite des nombres à virgule flottante littéraux que Jelly ne semble pas être capable de compresser, donc Pythagoras c'est.

+“Ȯịż’×µ½

Explication:

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

Le besoin de µséparateur me contrarie, mais je pense que c'est inévitable; Jelly a déjà enregistré un octet sur 05AB1E en pouvant deviner de quels arguments de nombreuses commandes ont besoin, mais dans ce cas, il ne peut pas deviner correctement jusqu'à la fin, j'ai donc dû lui donner un indice.

Jelly, 7 octets dans la page de codes de Jelly

דȮịż’½

Comme je l'ai expliqué dans mon autre réponse , l'approximation en série de l'approximation de Pythagore produit en fait de meilleurs résultats sur les longueurs incluses dans la question (au moins, elles sont plus proches des sorties d'exemple), et a également une formule plus courte. Pendant que je l'écrivais, j'ai réalisé qu'au lieu de calculer la racine carrée de 12742000 à l'avance, je pouvais d'abord multiplier le nombre par 12742000, puis la racine carrée les deux en même temps. Ceci est fondamentalement équivalent à l'autre formule sans l'addition, et en tant que tel, il peut être produit à partir du programme précédent en supprimant l'addition de celui-ci. Cela économise deux octets, car il analyse désormais sans ambiguïté et nous n'avons donc plus besoin d'un µ.


J'ai décidé de ne pas utiliser cette optimisation car elle ne donne pas les mêmes valeurs si vous regardez les centimètres (cf. sortie demandée) étant donné la plage de h. Cela permettrait également d'économiser 2 octets dans 05AB1E.
Osable

Avec l'optimisation, j'obtiens des sorties de 12105.081577585506 et 13260.452480967608; ceux-ci sont très proches de la sortie du scénario de test et arrondis à eux. Sans, j'obtiens 12105.087040166212 et 13260.459661716106, qui sont plus éloignés (et ce dernier est incorrect en centimètres, arrondi à 13260.46). Comme mentionné dans l'autre réponse, l'optimisation se trouve être plus proche de la valeur correcte que le code optimisé car il contient deux erreurs qui s'annulent en grande partie, plutôt qu'une seule qui n'a rien pour l'annuler.

Puisque vous venez de voter pour "Laisser ouvert" dans la file d'attente de révision, je suppose que vous pensez connaître les réponses aux questions pour lesquelles j'ai demandé des éclaircissements dans les commentaires. Veuillez donc modifier la question afin qu'elle ne soit pas ambiguë.
Peter Taylor

1
La question est sans ambiguïté: l'auteur doit connaître la distance de son ami pour l'aider à naviguer. Il peut déterminer la position de la torche avec une précision de 0,1 mètre (nous pouvons le déterminer à partir de l'histoire qui est racontée). Cela va inévitablement donner environ 1 mètre d'incertitude par rapport à la sortie à la distance actuelle (note: l'auteur dérive, il est donc peu probable qu'il se déplace très loin très rapidement…), et donc tout ce qui est approximativement aussi précis est susceptible d'être acceptable. Une partie du problème consiste à déterminer à quel point vous devez être précis dans cette situation!

1
La sortie demandée indique 2 décimales en mètres. La précision devrait donc être de 1 centimètre. Dans les commentaires à la question, OP a déclaré que h pouvait aller jusqu'à 100. Avec h = 100, il y a un écart de 14 centimètres par rapport à l'algorithme d'origine.
Osable

2

Rubis, 23

23 octets, en Km

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

25 octets, en m

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

1

Tcl, 49 octets:

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

Eh bien, je suis tout nouveau à Tcl, donc tous les conseils pour jouer au golf sont très appréciés. Comme mes autres réponses, invite à entrer la ligne de commande en kilomètres et les sorties en kilomètres. Essentiellement une adaptation Tcl de mes existants dcet pythonréponses.


il manque un s sur get s
sergiol

1

x86_64 + code machine SSE, 16 octets

Les octets du programme sont à gauche (en hexadécimal), il y a un démontage à droite pour le rendre un peu plus facile à lire. Il s'agit d'une fonction qui suit la convention x86_64 normale pour les fonctions prenant et retournant un nombre à virgule flottante simple précision (elle prend l'argument en% xmm0 et renvoie sa réponse dans le même registre, et utilise% xmm1 et% eax comme temporaires; ces sont les mêmes conventions d'appel qu'un programme C utilisera, et en tant que tel, vous pouvez appeler la fonction directement à partir d'un programme C, c'est ainsi que je l'ai testée).

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

Même avec un démontage, cependant, cela nécessite toujours une explication. Tout d'abord, il vaut la peine de discuter de la formule. La plupart des gens ignorent la courbure de la terre et utilisent la formule de Pythagore pour mesurer la distance. Je le fais aussi, mais j'utilise une approximation d'extension en série; Je ne prends que le terme relatif à la première puissance de l'entrée et j'ignore les troisième, cinquième, septième, etc. pouvoirs, qui n'ont tous qu'une très petite influence à cette courte distance. (En outre, l'approximation de Pythagore donne une valeur faible, tandis que les termes ultérieurs de l'expansion en série servent à réduire la valeur; en tant que tel, en ignorant un facteur mineur qui servirait à pousser l'approximation dans la mauvaise direction, il se trouve que j'obtiens un résultat plus précis en utilisant une formule moins précise.) La formule s'avère être √12742000 × √h;0x455f1980.

La prochaine chose qui pourrait dérouter les gens est pourquoi j'utilise des instructions vectorielles pour la racine carrée et la multiplication; %xmm0et %xmm1peut contenir quatre nombres à virgule flottante simple précision chacun, et je travaille sur les quatre. Le raisonnement ici est vraiment simple: leur codage est un octet plus court que celui des instructions scalaires correspondantes. Je peux donc faire en sorte que le FPU fasse un tas de travail supplémentaire de racine carrée et de multiplication des zéros afin de me sauver deux octets, dans une méthode qui rappelle très bien l'algorithme typique du langage de golf. (J'ai appelé l'assembleur x86 le langage du golf des assembleurs dans le chat il y a quelque temps, et je n'ai toujours pas changé d'avis à ce sujet.)

À partir de là, l'algorithme est très simple: charger %xmm1avec √12742000 via %eax(qui est plus court en termes d'octets que le charger depuis la mémoire), racine carrée de l'argument (et trois zéros), multiplier les éléments correspondants de %xmm1et %xmm0(nous ne nous soucions que sur le premier élément), puis revenez.


1

Minkolang v0.15, 22 octets

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

Essayez-le en ligne!

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 octets

Affiche la valeur en mètres

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


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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.