24
\$\begingroup\$

Define a function, s, which takes a number and returns the square root.

No use of library functions, such as Java's Math.sqrt() or PHP's built in sqrt(), allowed.

\$\endgroup\$
19
  • 3
    \$\begingroup\$ I think all solutions will be based on Newton approximation such as codemaestro.com/reviews/9 \$\endgroup\$
    – Alexandru
    Jan 28, 2011 at 0:56
  • 6
    \$\begingroup\$ How do you feel about exp(0.5*log(x))? \$\endgroup\$ Jan 28, 2011 at 2:07
  • 4
    \$\begingroup\$ The problem with this puzzle is that it lacks specifications for input range and tolerated error, it's kinda boring if "keep on adding a small number until result is reached" method is allowed, it's the shortest in any language. \$\endgroup\$ Jan 28, 2011 at 2:11
  • 2
    \$\begingroup\$ @jtjacques: Er...yes it does. Try a couple of cases. Make sure that you use the same base for exponentiation and logarithm. \$\endgroup\$ Jan 28, 2011 at 2:23
  • 2
    \$\begingroup\$ @jtjacques: Base agreement is key, many languages use log for the base 10 logarithm, so you might try exp(0.5*ln(x)) to get the natural log or pow10(0.5*log(x)) or similar. \$\endgroup\$ Jan 28, 2011 at 2:38

38 Answers 38

32
\$\begingroup\$

Python - 11 chars

Technically not a library function :)

input()**.5

As a function it's 16 chars

f=lambda x:x**.5
\$\endgroup\$
5
  • \$\begingroup\$ Smart, I like it. \$\endgroup\$
    – jtjacques
    Jan 28, 2011 at 1:25
  • 2
    \$\begingroup\$ It's questionable whether this falls under a built-in function (it calls __pow__). But then even * is a built-in. \$\endgroup\$
    – moinudin
    Jan 29, 2011 at 11:37
  • \$\begingroup\$ Would have preferred it as a function, but I'll give you the accept for the ingenuity. \$\endgroup\$
    – jtjacques
    Jan 31, 2011 at 15:45
  • 19
    \$\begingroup\$ @jtjacques What ingenuity? IMHO, this is the one the most obvious ways around the rules. \$\endgroup\$ May 16, 2011 at 3:48
  • \$\begingroup\$ I think the function has to be called 's', not 'f'. \$\endgroup\$ Jul 8, 2015 at 17:56
24
\$\begingroup\$

Python (13 chars)

f=.5.__rpow__

This is equivalent to f=lambda x:x**.5, but 3 bytes shorter.

\$\endgroup\$
17
\$\begingroup\$

Python - 41 chars

Takes a while to run for large numbers :)

n=input()
i=0
while i*i<n:i+=1e-9
print i
\$\endgroup\$
1
  • 1
    \$\begingroup\$ For me, it takes a while even for 2. \$\endgroup\$
    – alexia
    Apr 30, 2014 at 13:44
14
\$\begingroup\$

Java (163)

Implementing a double precision square root calculator by making use of the fast invert square root stuff from quake and a new constant for the 64bit floats. In java. Yay for verbosity.

public double i(double a){double b=a/2;long c=0x5fe6ec85e7de30daL-(Double.doubleToRawLongBits(a)>>1);a=Double.longBitsToDouble(c);return a*(1.5-b*a*a);};s=1/i(x);
\$\endgroup\$
9
\$\begingroup\$

J, 6, 5

Using power:

^&0.5

Or, perhaps more mnemonically:

^&1r2

Using the slightly less "cheaty" method, exp(log(x)/2).

-:&.^.

Except since exp is the inverse of log, we simply "halve (-:) under (&.) log (^.)"

Not that normally a J programmer would not name a method this short; he'd simply embed in in a larger program.

\$\endgroup\$
8
\$\begingroup\$

Haskell, 9 characters

s=(**0.5)

Similar to @gnibbler's Python solution.

\$\endgroup\$
5
\$\begingroup\$

LISP (66)

Using Babylonian method.

(defun s(A)
   (do((x 1(*(+ x(/ A x)).5))(n 100(1- n)))((zerop n)x)))
\$\endgroup\$
4
\$\begingroup\$

Naive solution, accepts only positive integer inputs.

s n=foldr (\x a->x*x==n||a) False [1..]

Haskell, 39 characters.

\$\endgroup\$
1
  • 6
    \$\begingroup\$ remove spaces? s n=foldr(\x a->x*x==n||a)False[1..] \$\endgroup\$
    – Ming-Tang
    Jan 28, 2011 at 3:51
4
\$\begingroup\$

Python - 65

A simple solution using Newton's method.

def s(x):
 t=1.0
 while 1e-9<abs(x-t*t):t-=(t*t-x)/2/t
 return t
\$\endgroup\$
4
\$\begingroup\$

C with some bad form and deprecated features:

s(int n,int g){return g*g-n?s(n,random()%n):g;}

If your compiler is enough of a liberal hippie, it should be possible to call s(n) and (eventually) receive the desired value.

\$\endgroup\$
2
  • \$\begingroup\$ You can save 8 characters, and allow calling s(n) (at least in GCC), by changing s(int n,int g) to s(n,g). \$\endgroup\$
    – Joey Adams
    Mar 18, 2011 at 4:20
  • \$\begingroup\$ Save 2 more chars by changing random() to rand(). \$\endgroup\$
    – Paul R
    Jun 14, 2011 at 14:36
3
\$\begingroup\$
return 1.f/InvSqrt(x);

InvSqrt of course courtesy of Quake.

What, you mean you wanted an accurate result?

\$\endgroup\$
1
  • \$\begingroup\$ Well to the limit of the return type, and also one which does not use a library. \$\endgroup\$
    – jtjacques
    Jan 28, 2011 at 1:08
3
\$\begingroup\$
def sqrt_newton(x):
 f,g,w,d=lambda a:a*a-x,lambda a:2.0*a,x/2.0,1e-4
 while abs(f(w))>d:w-=(f(w)/2.0/w)
 return w

reduced version of https://gist.github.com/713104

\$\endgroup\$
1
  • 3
    \$\begingroup\$ And the size is ... \$\endgroup\$ Nov 8, 2011 at 5:35
3
\$\begingroup\$

C++ (61)

Uses Heron's Method:

f64 s(f64*x,u64 n=9){*x=(x[1]/*x+*x)/2;return n?s(x,--n):*x;}

Recursion, pointers, optional arguments, and ternary operators FTW!


Usage:

f64 x[2] = {12.0, 12.0};
std::cout << s(x);
\$\endgroup\$
2
\$\begingroup\$

C++ (35)

f64 s(f64 x){return exp(log(x)/2);}

I promise I didn't use sqrt()!

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

ActionScript3 (53)

Using Newton's method. (Hooray 4 IEEE 754)

function s(b,d=2){return b==d*d?d:s(b,d-(d*d-b)/2/d)}

I know I'm TOO late but I just wanted to write something I did :(

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

GolfScript - 21

It uses the Babylonian method and works only with integers. According to my tests, it's good for up to 56 digits.

{1{.2$\/+2/}99*\;}:s;

Usage: 1000 s -> 31

I think this is the shortest solution so far that doesn't call some kind of power function or external library.

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

k (17 chars)

Iterative (implementation of Babylonian method):

{{.5*y+x%y}[x]/x}

Iterates until two successive values are equal

Example:

sqrt[1234] = {{0.5*y+x%y}[x]/x}1234
1b

Also the mandatory xexp[;0.5] for 10.

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

JavaScript, 121

No, it doesn't even come close, but it is more optimal than other solutions and doesn't use Math.pow with fractions.

s=n=>{for(var c=Math.pow(10,(''+Math.floor(n)).length),v=0,l;(l=v*v<n),c>1e-10;l!=v*v<n?c/=10:0)v*v<n?v+=c:v-=c;return v}
\$\endgroup\$
9
  • \$\begingroup\$ You're missing the function name there. Should be something like function s(n). \$\endgroup\$
    – alexia
    Apr 30, 2014 at 10:41
  • \$\begingroup\$ @nyuszika7h: It’s a function literal. \$\endgroup\$
    – Ry-
    Apr 30, 2014 at 14:28
  • \$\begingroup\$ But you would need to assign that to a variable (which is the same "penalty" as using my previous suggestion). I don't see Python solutions like lambda x: ... either, I see solutions like f=lambda x: .... \$\endgroup\$
    – alexia
    Apr 30, 2014 at 14:30
  • \$\begingroup\$ @nyuszika7h: Their loss. This code is a function. \$\endgroup\$
    – Ry-
    Apr 30, 2014 at 14:30
  • 1
    \$\begingroup\$ Also, sorry if it came off as being rude, I didn't mean to be. \$\endgroup\$
    – alexia
    Apr 30, 2014 at 14:46
1
\$\begingroup\$

Mathematica 27

f@x_:=Nest[(#+x/#)/2&,1.,9]
\$\endgroup\$
1
\$\begingroup\$

Golf-Basic 84, 9 characters

i`Ad`A^.5

As a function, 15 characters:

i`A:Return A^.5
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 36 (or 14 without the function)

function s(n){return Math.pow(n,.5)}
\$\endgroup\$
1
\$\begingroup\$

AWK, 8

1,$0^=.5

Following solution can handle all values except 0

AWK, 6

$0^=.5
\$\endgroup\$
1
\$\begingroup\$

Befunge 98 - 18

&00pv  
0*::<+1vj!`g0

This program takes an input number from the user, and ends by pushing the integer square root on the stack (note that you said square root, but didn't specify whether floating point was necessary). Here is a function (well, closest thing to one) (requiring free access to cell 00) (15 chars):

00p::*00g`!jv1+
\$\endgroup\$
1
\$\begingroup\$

In these I expect the byte to be squared is in the current cell. It needs 8 cells to the right empty and it will have answers in the 4 cells starting from where the number was. These are:

  1. integer result
  2. a alternative result (would be the same or one higher if those multiplied is closer to the argument)
  3. remainder
  4. flag for negative remainder

Extended BrainFuck: 310

>+4>15+4<[>>+<+<[->[->->>+<<]>[-<+>>]<+<<]>[-]>[-]3<[->+>>+3<]>[-<+>]4>[-<+3<+4>]<<[->-[>+>>]>[+[-<+>]>+>>]5<]3>[-3<+3>]<[->>+>+3<]<[->+4>+5<]>+[>>[-<]<[>]<-]3>+<[[-]>[-]>[-4<+4>]5<+<+4>]>[->[-]<[-3<+3>]]3<[->+<]<<[->>+4<->>]<+<[-[+3>[-]>>[-]4<-]>[-5>+4<]<]>[->]<<]<[-]5>[-4<+<+5>]>>[-6<+6>]<[-3<+3>]<<[-<<+>>]

It turns into the following:

BrainFuck: 390 (the same as above run through the compiler)

>+>>>>+++++++++++++++<<<<[>>+<+<[->[->->>+<<]>[-<+>>]<+<<]>[-]>[-]<<<[->+>>+<<<]>[-<+>]>>>>[-<+<<<+>>>>]<<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>[-<<<+>>>]<[->>+>+<<<]<[->+>>>>+<<<<<]>+[>>[-<]<[>]<-]>>>+<[[-]>[-]>[-<<<<+>>>>]<<<<<+<+>>>>]>[->[-]<[-<<<+>>>]]<<<[->+<]<<[->>+<<<<->>]<+<[-[+>>>[-]>>[-]<<<<-]>[->>>>>+<<<<]<]>[->]<<]<[-]>>>>>[-<<<<+<+>>>>>]>>[-<<<<<<+>>>>>>]<[-<<<+>>>]<<[-<<+>>]

It's Newtons method starting at guess 16 and goes downwards. It stops when the last iteration didn't make a different integer result. This is actualy from the sqrt macro of EBF since I use it to implement print-string operator |. Here's the part from EBF source ungolfed:

; sqrt ^0  uses  9 cells that need to be empty
; will be fuzzy after calling because of divmod
; returns ^0 result
;         ^1 same as ^0 or it increased by 1. typically will ^2*^3 be closerto the requested argument than ^2*^2
;         ^2 remainder
;         ^3 indicates if remainder is negative
{sqrt
  check for wrong usage !diff:diff
  :in:guess:temp:cur:div:mod:res:indicator
  @in
  $guess+     ;initial guess is 16, but
  $mod 15+    ; its in mod and incremented (rounded up)
  $guess(     ; worst case is 1 with 5 iterations
      $cur+$temp+
      $guess(-$temp[->-$mod+$cur]>[@cur-$temp+$div]$cur+)
      $temp(-)$cur(-)
      $in(-$guess+$cur+)
      $guess(-$in+)
      $mod(-$div+$guess+)
      $cur &roundivmod ; remainder wil now be in mod
      $mod(-$res+)
      $cur(-$mod+$guess-)
      $temp+
      $guess[-[+$div(-)$res(-)$temp-]>[-@temp$indicator+$cur]$temp]>[-@temp>]
  )
  $in(-)
  $mod(-$guess+$in+)
  $indicator(-$guess+)
  $res(-$cur+)
  $div(-$temp+)
  $in
  !indicator!res!mod!div!cur!temp!guess!in
}

;; helper macros
; roundivmod uses divmod and puts the rounded result in ^0 and indication of rounded in ^1
; and a remainder (which ^1 is an indication is either reduction or inrement) in ^2
{roundivmod
    &divmod @cur
    ; *0|n-rem|rem|res|
    >>>(-<<<+)
    <(->>+>+) make double copy of remainder
    ; res|n-rem|0|0|rem|rem
    <(->+>>>>+)
    ; res|0|n-rem|0|rem|rem|n-rem
    >+[>>[-<]<[>]<-]
    >>>+<(
       [-]>[-]
       >(-<<<<+)
       <<<<<+<+
      )
     >(-
        >[-]
        <(-<<<+)
      )
  end divide
}

; this does the divmod. compiler is fuzzy after so caller must fix position to calling
{divmod[->-[>+>>]>[+[-<+>]>+>>]<<<<<]}
\$\endgroup\$
0
\$\begingroup\$

Scala 78 chars:

type D=Double
def q(x:D,g:D=9):D=if(math.abs(g*g-x)<.001)g else q(x,(g+x/g)/2)

invocation:

scala> q(12345)
res36: D = 111.10805572305925
\$\endgroup\$
0
\$\begingroup\$

Python, 44

def s(x):t=1.;exec"t=(t+x/t)/2;"*99;return t

Tested with:

for x in [0, (3+5**0.5)/2, 1000, 10**5, 10**11]:
    print x, '->', s(x)

Output:

0 -> 1.57772181044e-30
2.61803398875 -> 1.61803398875
1000 -> 31.6227766017
100000 -> 316.227766017
100000000000 -> 316227.766017

Python, 50 49

In case you like recursion:

s=lambda x,t=1.,r=99:r and s(x,t/2+x/t/2,r-1)or t

Same testing code, same output.

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

Postscript 94 89

Babylonian method. Iterates until successive values are equal.

s{dup 2 div{2 copy div 1 index add .5 mul
2 copy eq{exit}if exch pop}loop pop exch pop}def 

Commented:

/s{
    dup 2 div  % S x
    {  % S x
        2 copy div  % S x S/x 
        1 index add .5 mul  % S x (S/x+x)/2
        2 copy eq { exit } if  % S x (S/x+x)/2
        exch pop  % S (S/x+x)/2:->x
    }loop   
    pop exch pop
}def
\$\endgroup\$
0
\$\begingroup\$

228 ( a lot but pure bash only! ;)

For the count:

x=(600000 200000);z=${x[$(($1&1))]} y=1;while [ $y -ne $z ] ;do y=$z;printf -v z "%u" $(((${y}000+${1}00000000000/${y})/2));printf -v z "%.0f" ${z:0:${#z}-3}.${z:${#z}-3};done;z=0000$z;printf "%.3f\n" ${z:0:${#z}-4}.${z:${#z}-4}

As a function:

sqrt() {
    local -a xx=(600000 200000)
    local x1=${xx[$(($1&1))]} x0=1
    while [ $x0 -ne $x1 ] ;do
    x0=$x1
    printf -v x1 "%u" $(( (${x0}000 + ${1}00000000000/${x0} )/2 ))
    printf -v x1 "%.0f" ${x1:0:${#x1}-3}.${x1:${#x1}-3}
    done
    x1=0000$x1
    printf "%.3f\n" ${x1:0:${#x1}-4}.${x1:${#x1}-4}
}

sqrt 2000000
1414.214

sqrt 1414214
1189.207

echo $((1189207000/1414214))
840

(Nota: 840 x 1189 is A0 paper size in milimeters ;-)

The same, but working under , , , and (busybox):

sqrt() {
    _val=$1
    set -- 6 2
    x1=$(eval echo \$$((1+(_val&1))))00000 x0=1
    while [ $x0 -ne $x1 ] ;do
    x0=$x1
    x1=000$(( (${x0}000 + ${_val}000000000/${x0} )/2 ))
    x1=$(printf "%.0f" $(echo $x1|sed 's/\(...\)$/.\1/'))
      done
    printf "%.3f\n" $(echo $x1|sed 's/\(...\)$/.\1/')
}
\$\endgroup\$
2
  • \$\begingroup\$ The portable version seems to work fine in zsh too. \$\endgroup\$
    – manatwork
    Dec 16, 2013 at 8:31
  • \$\begingroup\$ @manatwork Thanks I'v forgot them! \$\endgroup\$ Dec 16, 2013 at 8:36
0
\$\begingroup\$

dc, 46 chars

Babylonian method - iterative with given precision:

Fk?sp?sn1[ddstlnr/+2/pdlt-[0r-]sbd0>blp<a]dsax

Takes precision and N from stdin. Example invocation (first number is the precision, second number is N:

{ echo 0.0000001 ; echo 489 ; } | dc -e'Fk?sp?sn1[ddstlnr/+2/pdlt-[0r-]sbd0>blp<a]dsax'

It prints all the iterations, just for fun. Printing only last one is trivial change - just move the p behind /+2/ at the end of the program.

Explanation:

  • Fk sets precision to 15 (see the hexa trick here)
  • ?sp and ?sn asks for input and stores it to the registers
  • 1 is the original seed
  • the iteration is computed by ddstlnr/+2/. Then, dlt- computes difference from previous iteration. [0r-]sbd0>b performs absolute value of the difference, and if it is greater than the specified precision, loop continues - lp<a.
\$\endgroup\$
0
\$\begingroup\$

CoffeeScript (12)

s=(n)->n**.5

Thanks to gnibbler's post for the .5 idea, I wouldn't have remembered that by myself.

\$\endgroup\$

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