10
\$\begingroup\$

Inspired by this video by tecmath.

An approximation of the square root of any number x can be found by taking the integer square root s (i.e. the largest integer such that s * s ≤ x) and then calculating s + (x - s^2) / (2 * s). Let us call this approximation S(x). (Note: this is equivalent to applying one step of the Newton-Raphson method).

Though this does have quirk, where S(n^2 - 1) will always be √(n^2), but generally it will be very accurate. In some larger cases, this can have a >99.99% accuracy.

Input and Output

You will take one number in any convienent format.

Examples

Format: Input -> Output

2 -> 1.50 5 -> 2.25 15 -> 4.00 19 -> 4.37 // actually 4.37 + 1/200 27 -> 5.20 39 -> 6.25 47 -> 6.91 // actually 6.91 + 1/300 57 -> 7.57 // actually 7.57 + 1/700 2612 -> 51.10 // actually 51.10 + 2/255 643545345 -> 25368.19 // actually 25,368.19 + 250,000,000/45,113,102,859 35235234236 -> 187710.50 // actually 187,710.50 + 500,000,000/77,374,278,481 

Specifications

  • Your output must be rounded to at least the nearest hundredth (ie. if the answer is 47.2851, you may output 47.29)

  • Your output does not have to have following zeros and a decimal point if the answer is a whole number (ie. 125.00 can be outputted as 125 and 125.0, too)

  • You do not have to support any numbers below 1.

  • You do not have to support non-integer inputs. (ie. 1.52 etc...)

Rules

Standard Loopholes are forbidden.

This is a , so shortest answer in bytes wins.

\$\endgroup\$
10
  • \$\begingroup\$ Sandbox \$\endgroup\$ Commented Oct 26, 2017 at 19:06
  • 3
    \$\begingroup\$ Note: s + (x - s^2) / (2 * s) == (x + s^2) / (2 * s) \$\endgroup\$ Commented Oct 26, 2017 at 19:31
  • \$\begingroup\$ My solutions: Pyth, 25 bytes; 14 bytes \$\endgroup\$ Commented Oct 26, 2017 at 20:31
  • \$\begingroup\$ Does it need to be accurate to at least 2 digits? \$\endgroup\$ Commented Oct 27, 2017 at 1:01
  • \$\begingroup\$ @totallyhuman Yes. 47.2851 can be represented as 47.28, but no more inaccurate. \$\endgroup\$ Commented Oct 27, 2017 at 1:05

19 Answers 19

4
\$\begingroup\$

Haskell, 34 bytes

f x=last[s+x/s|s<-[1..x],s*s<=x]/2 

Try it online!

Explanation in imperative pseudocode:

results=[] foreach s in [1..x]: if s*s<=x: results.append(s+x/s) return results[end]/2 
\$\endgroup\$
0
4
\$\begingroup\$

Java (OpenJDK 8), 32 bytes

n->(n/(n=(int)Math.sqrt(n))+n)/2 

Try it online!

Explanations

The code is equivalent to this:

double approx_sqrt(double x) { double s = (int)Math.sqrt(x); // assign the root integer to s return (x / s + s) / 2 } 

The maths behind:

s + (x - s²) / (2 * s) = (2 * s² + x - s²) / (2 * s) = (x + s²) / (2 * s) = (x + s²) / s / 2 = ((x + s²) / s) / 2 = (x / s + s² / s) / 2 = (x / s + s) / 2 
\$\endgroup\$
3
  • \$\begingroup\$ This doesn't appear to handle the specification: Your output must be rounded to at least the nearest hundredth \$\endgroup\$ Commented Oct 27, 2017 at 21:04
  • 2
    \$\begingroup\$ Well, it is rounded to lower than the nearest hundredth, so it's totally valid. \$\endgroup\$ Commented Oct 27, 2017 at 21:48
  • \$\begingroup\$ Ah, I see, my misunderstanding. \$\endgroup\$ Commented Oct 27, 2017 at 21:51
4
\$\begingroup\$

Python 2, 47 ... 36 bytes

-3 bytes thanks to @JungHwanMin
-1 byte thanks to @HyperNeutrino
-2 bytes thanks to @JonathanFrech
-3 bytes thanks to @OlivierGrégoire

def f(x):s=int(x**.5);print(x/s+s)/2 

Try it online!

\$\endgroup\$
7
  • \$\begingroup\$ -2 bytes: s+(x-s*s)/s/2 to (x+s*s)/s/2 \$\endgroup\$ Commented Oct 26, 2017 at 19:31
  • \$\begingroup\$ -2 bytes using a function \$\endgroup\$ Commented Oct 26, 2017 at 19:41
  • \$\begingroup\$ @HyperNeutrino I only get -1 byte \$\endgroup\$ Commented Oct 26, 2017 at 19:46
  • \$\begingroup\$ Oh sorry I accidentally deleted a character after testing and then counted the bytes after :P yeah just -1 \$\endgroup\$ Commented Oct 26, 2017 at 19:53
  • \$\begingroup\$ Can you not omit +.0 and replace /s/2 with /2./s, saving two bytes? \$\endgroup\$ Commented Oct 26, 2017 at 21:47
4
\$\begingroup\$

R, 43 bytes 29 bytes

x=scan() (x/(s=x^.5%/%1)+s)/2 

Thanks to @Giuseppe for the new equation and help in golfing of 12 bytes with the integer division solution. By swapping out the function call for scan, I golfed another couple bytes.

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 35 bytes; more generally, you can use the "header" field of TIO and put a f <- to assign the function. But still, nice solution, make sure you read Tips for golfing in R when you get a chance! \$\endgroup\$ Commented Oct 27, 2017 at 18:36
  • 1
    \$\begingroup\$ 31 bytes using Oliver Gregoire's formula \$\endgroup\$ Commented Oct 27, 2017 at 18:40
3
\$\begingroup\$

MATL, 12 9 bytes

X^kGy/+2/ 

Try it online!

\$\endgroup\$
3
\$\begingroup\$

APL (Dyalog), 20 16 bytes

{.5×s+⍵÷s←⌊⍵*.5} 

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Jelly,  8  7 bytes

-1 byte thanks to Olivier Grégoire's simplified mathematical formula - see their Java answer.

÷ƽ+ƽH 

Try it online!

How?

÷ƽ+ƽH - Link: number, n ƽ - integer square root of n -> s ÷ - divide -> n / s ƽ - integer square root of n -> s + - add -> n / s + s H - halve -> (n / s + s) / 2 
\$\endgroup\$
2
  • \$\begingroup\$ 7 bytes: ÷ƽ+ƽH First time trying to use Jelly so I might be wrong. I wish I knew how to store ƽ, though, to not repeat it. That might save another byte. \$\endgroup\$ Commented Oct 27, 2017 at 13:10
  • \$\begingroup\$ Thanks @OlivierGrégoire! ƽɓ÷⁹+H would not recalculate the integer root, but it's also 7. ɓ starts a new dyadic chain with swapped arguments and then refers to that chain's right argument (i.e. the result of ƽ). ƽɓ÷+⁹H would work here too. \$\endgroup\$ Commented Oct 27, 2017 at 18:30
2
\$\begingroup\$

JavaScript (ES7), 22 bytes

x=>(s=x**.5|0)/2+x/s/2 

We don't really need an intermediate variable, so this can actually be rewritten as:

x=>x/(x=x**.5|0)/2+x/2 

Test cases

let f = x=>x/(x=x**.5|0)/2+x/2 console.log(f(2)) // 1.50 console.log(f(5)) // 2.25 console.log(f(15)) // 4.00 console.log(f(19)) // 4.37 console.log(f(27)) // 5.20 console.log(f(39)) // 6.25 console.log(f(47)) // 6.91 console.log(f(57)) // 7.57 console.log(f(2612)) // 51.10 console.log(f(643545345)) // 25368.19 console.log(f(35235234236)) // 187710.50

\$\endgroup\$
2
\$\begingroup\$

C, 34 bytes

Thanks to @Olivier Grégoire!

s; #define f(x)(x/(s=sqrt(x))+s)/2 

Works only with float inputs.

Try it online!

C,  41   39  37 bytes

s; #define f(x).5/(s=sqrt(x))*(x+s*s) 

Try it online!

C,  49   47   45  43 bytes

s;float f(x){return.5/(s=sqrt(x))*(x+s*s);} 

Try it online!


Thanks to @JungHwan Min for saving two bytes!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 47 bytes; edit: Thank you, but credit @JungHwanMin for finding that. \$\endgroup\$ Commented Oct 26, 2017 at 19:50
  • \$\begingroup\$ 34 bytes \$\endgroup\$ Commented Oct 27, 2017 at 8:43
2
\$\begingroup\$

Haskell, 40 bytes

Another one bytes the dust thanks to H.PWiz.

f n|s<-realToFrac$floor$sqrt n=s/2+n/s/2 

Try it online!

\$\endgroup\$
0
2
\$\begingroup\$

AWK, 47 44 38 bytes

{s=int($1^.5);printf"%.2f",$1/2/s+s/2} 

Try it online!

NOTE: The TIO like has 2 extra bytes for \n to make the output prettier. :)

It feels like cheating a bit to use sqrt to find the square root, so here is a version with a few more bytes that doesn't.

{for(;++s*s<=$1;);s--;printf("%.3f\n",s+($1-s*s)/(2*s))} 

Try it online!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ well you could say this is AWKward. I’ll show myself out. edit: originally I planned for the question to shun using sqrt, but there’s too many answers and I’ll get tort if I change it so my original idea works. \$\endgroup\$ Commented Oct 27, 2017 at 19:17
  • \$\begingroup\$ 'AWK' puns are fun :) \$\endgroup\$ Commented Oct 28, 2017 at 13:19
  • \$\begingroup\$ instead of sqrt($1) you can use $1^.5 \$\endgroup\$ Commented Oct 29, 2017 at 22:42
  • \$\begingroup\$ Thanks @Cabbie407 don't know why I didn't think of that. \$\endgroup\$ Commented Oct 30, 2017 at 13:52
  • 1
    \$\begingroup\$ You're welcome. Some other things: you don't need the \n to get the output, the printf in awk doesn't need parentheses and the formula can be shortened to s/2+$1/s/2, which results in {s=int($1^.5);printf"%.2f",s/2+$1/s/2}. Sorry if this comment seems rude. \$\endgroup\$ Commented Oct 31, 2017 at 0:18
2
\$\begingroup\$

Vyxal, 8 bytes

:√I:‟/+½ 

Try it Online!

For n=2

: # Dup -> [2,2] √ # Square root -> [2,√2] I # Round -> [2,1] : # Dup -> [2,1,1] ‟ # Rotate stack right -> [1,2,1] / # Divide -> [1,2] + # Add -> 3 ½ # Halve -> 1.5 
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 9 bytes

DtïD.Á/+; 

Try it online!

Port of my Vyxal answer

\$\endgroup\$
1
\$\begingroup\$

Racket, 92 bytes

Thanks to @JungHwan Min for the tip in the comment section

(λ(x)(let([s(integer-sqrt x)])(~r(exact->inexact(/(+ x(* s s))(* 2 s)))#:precision'(= 2)))) 

Try it online!

Ungolfed

(define(fun x) (let ([square (integer-sqrt x)]) (~r (exact->inexact (/ (+ x (* square square)) (* 2 square))) #:precision'(= 2)))) 
\$\endgroup\$
1
\$\begingroup\$

PowerShell, 54 bytes

param($x)($x+($s=(1..$x|?{$_*$_-le$x})[-1])*$s)/(2*$s) 

Try it online! or Verify some test cases

Takes input $x and then does exactly what is requested. The |? part finds the maximal integer that, when squared, is -less-than-or-equal to the input $x, then we perform the required calculations. Output is implicit.

\$\endgroup\$
2
  • \$\begingroup\$ Wow. I've never been able to comprehend how people golf in Windows Powershell \$\endgroup\$ Commented Oct 26, 2017 at 20:13
  • \$\begingroup\$ @StanStrum You're not alone, lol. :D \$\endgroup\$ Commented Oct 26, 2017 at 20:24
1
\$\begingroup\$

Husk, 9 bytes

½Ṡ§+K/(⌊√ 

Try it online!

There is still something ugly in this answer, but I can't seem to find a shorter solution.

Explanation

I'm implementing one step of Newton's algorithm (which is indeed equivalent to the one proposed in this question)

½Ṡ§+K/(⌊√ §+K/ A function which takes two numbers s and x, and returns s+x/s Ṡ Call this function with the input as second argument and (⌊√ the floor of the square-root of the input as first argument ½ Halve the final result 
\$\endgroup\$
2
  • \$\begingroup\$ I think you want actual division, rather than ÷ \$\endgroup\$ Commented Oct 26, 2017 at 23:24
  • \$\begingroup\$ @H.PWiz whoops, I do, thank you. That was a remain from an experiment to find other solutions \$\endgroup\$ Commented Oct 26, 2017 at 23:29
1
\$\begingroup\$

Pyt, 11 10 bytes

←Đ√⌊Đ↔⇹/+₂ 

Explanation

code explanation stack ← get input [input] Đ duplicate ToS [input,input] √⌊ calculate s [input,s] Đ duplicate ToS [input,s,s] ↔ reverse stack [s,s,input] ⇹ swap ToS and SoS [s,input,s] / divide [s,input/s] + add [s+input/s] ₂ halve [(s+input/s)/2] implicit print 
\$\endgroup\$
11
  • \$\begingroup\$ Just saw this and it was a good minute until I realised it’s not Pyth. Great answer. \$\endgroup\$ Commented Dec 25, 2017 at 17:47
  • \$\begingroup\$ Yeah, it's a little language I've been thinking about for a while and just decided to actually make. \$\endgroup\$ Commented Dec 25, 2017 at 17:51
  • \$\begingroup\$ Is ToS top-of-stack... and if so, what’s SoS? \$\endgroup\$ Commented Dec 25, 2017 at 17:53
  • \$\begingroup\$ ToS is top of stack, and SoS is second on stack \$\endgroup\$ Commented Dec 25, 2017 at 17:54
  • \$\begingroup\$ Nice, I’ll see if I can delve into this language; I like it! \$\endgroup\$ Commented Dec 25, 2017 at 17:55
1
\$\begingroup\$

Milky Way, 17 14 bytes

-3 bytes by using Olivier Grégoire's formula

^^':2;g:>/+2/! 

Try it online!

Explanation

code explanation stack layout ^^ clear preinitialized stack [] ': push input and duplicate it [input, input] 2; push 2 and swap ToS and SoS [input, 2, input] g nth root [input, s=floor(sqrt(input))] : duplicate ToS [input, s, s] > rotate stack right [s, input, s] / divide [s, input/s] + add [s+input/s] 2/ divide by 2 [(s+input/s)/2] ! output => (s+input/s)/2 
\$\endgroup\$
2
  • \$\begingroup\$ shouldn't that be floor instead of ceil? \$\endgroup\$ Commented Dec 25, 2017 at 15:56
  • \$\begingroup\$ @mudkip201 Updated, thanks \$\endgroup\$ Commented Dec 25, 2017 at 22:28
0
\$\begingroup\$

C# (.NET Core), 39 bytes

v=>(v/(v=(int)System.Math.Sqrt(v))+v)/2 

Try it online!

A C# version of Olivier Grégoire's Java answer.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.