Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Today I went fishing alone with my canoe, unfortunately I fell asleep and the stream brought me away, I lost my oars, now it's night and I am lost in the ocean! I can't see the coast so I must be far away!

I have my cell phone but is malfunctional because it got wet by the salty water, I can't talk or hear anything because the mic and phone speaker are broken, but I can send SMS to my friend who is on the coast's beach!

My friend has a very powerful torch and he raised it on top of bamboo's canes to show me the right direction, but I can’t row because I have no oars, so I must tell him how far I am so he can send someone to catch me!

My friend told me that he is keeping the torch at 11.5 meters on the sea level, and I can see the light right over the horizon. Now I only remember from the school that the Earth radius should be 6371 Km at the sea level, and I’m sittin in my canoe so you can assume that my eyes are at sea level too.

Since the currents are moving me moment by moment, my friend is raising the torch from time to time (now it’s at 12.3 meters), please write a full program or function that will help me to calculate the distance from my friend’s position!

Take from standard input the torch height at the sea level, which I see right on top of the horizon, and output the distance between me and my friend.

Here is a diagram (not to scale):

enter image description here

The orange point labelled M is me, the red point labelled T is the torch. You're given h as input and should return the length of the green line.

Test cases:

All values in metres. You can use kilometres instead if you wish.

11.5 > 12105.08
13.8 > 13260.45

Shortest code wins.

share|improve this question
    
Does the result have to be mathematically correct or is it ok if the first 2 decimals are ok? I mean that hxh is small in comparison to 2xRxh and can be neglected for small distances. (R is the radius of Earth and h is the height of the torch). – Osable 20 hours ago
    
@Osable first 2 decimals are ok if you output in meters – Mario 20 hours ago
    
What is the range of input? – Osable 20 hours ago
    
@Osable you can consider the input to be from 0 to 100 (even too much than necessary/possible in this case). – Mario 19 hours ago
    
Ok maybe h² is not that negligible within a centimeter if it goes up to 100 meters. – Osable 19 hours ago

dc, 16 11 bytes:

?d12742+*vp

Prompts for input through command line in kilometers and then outputs distance in kilometers.

Explanation

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

This takes advantage of the following:

((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
share|improve this answer

jq, 18 characters

(12742e3+.)*.|sqrt

Yet another copy of the same formula.

Sample run:

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

On-line test

share|improve this answer

Haskell, 22 bytes

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

Usage:

Prelude> d 11.5
12105.087040166212

Pointfree: (23 bytes)

sqrt.((*)=<<(+12742e3))
share|improve this answer

05AB1E, 13 12 10 bytes

Saved 2 bytes thanks to Emigna.

Since there is no trigonometric functions to be called using OP's assumption that the earth is locally a plane, it becomes possible to make an 05AB1E solution.

•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

Try it online!

share|improve this answer
1  
12742000 can be written as •1#oC• – Emigna 18 hours ago
    
For reference, it would have been 9 bytes: •1#oC•+*t in 2sable – Emigna 18 hours ago
    
Does a string sourrounded with depict a... base 214 number? 05AB1E suffers a lack of documentation on such special functions sometimes. Nice 2sable answer also. I found out about it a few days ago but I didn't think about using it for this question. – Osable 18 hours ago
    
Correct. It is a base 10 number encoded in base 214. – Emigna 18 hours ago
    
The result can be achieved also by trigonometry but is probably longer. – Mario 17 hours ago

R, 29 bytes

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

Takes input from stdin

share|improve this answer

Python, 34 26 bytes:

(-8 bytes thanks to Osable!)

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

An anonymous lambda function. Takes input in kilometers and outputs in kilometers. Invoke as print(<Function Name>(<Input>)).

share|improve this answer
    
lambda i:(i*(i+12742))**.5 would be even shorter. – Osable 20 hours ago
    
@Osable Nice! I was just about to do that. :) – R. Kap 20 hours ago
    
If there is mathematical tolerance, given the discrepancy between i and 12742, the expression can be shortened so: (i*12742)**.5 – Osable 20 hours ago

PHP, 34 bytes

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

breakdown

   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

so far, this is identical to the old Mathematica answer

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

now all that´s left to do is to add input =$argv[1] and output <?= - done

share|improve this answer

Mathematica, 16 bytes

Either of these works for both input and output in kilometres:

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

This is a simple application of Pythagoras to the 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)
share|improve this answer

Tcl, 49 bytes:

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

Well, I am brand new to Tcl, so any tips for golfing this down is highly appreciated. Like my other answers, prompts for command line input in kilometers and outputs in kilometers. Essentially a Tcl adaptation of my existing dc and python answers.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.