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.
Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It only takes a minute to sign up.
Sign up to join this communityTechnically not a library function :)
input()**.5
As a function it's 16 chars
f=lambda x:x**.5
__pow__
). But then even *
is a built-in.
\$\endgroup\$
f=.5.__rpow__
This is equivalent to f=lambda x:x**.5
, but 3 bytes shorter.
Takes a while to run for large numbers :)
n=input()
i=0
while i*i<n:i+=1e-9
print i
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);
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.
LISP (66)
Using Babylonian method.
(defun s(A)
(do((x 1(*(+ x(/ A x)).5))(n 100(1- n)))((zerop n)x)))
Naive solution, accepts only positive integer inputs.
s n=foldr (\x a->x*x==n||a) False [1..]
Haskell, 39 characters.
s n=foldr(\x a->x*x==n||a)False[1..]
\$\endgroup\$
Jan 28, 2011 at 3:51
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
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.
s(n)
(at least in GCC), by changing s(int n,int g)
to s(n,g)
.
\$\endgroup\$
Mar 18, 2011 at 4:20
random()
to rand()
.
\$\endgroup\$
return 1.f/InvSqrt(x);
InvSqrt of course courtesy of Quake.
What, you mean you wanted an accurate result?
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
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);
f64 s(f64 x){return exp(log(x)/2);}
I promise I didn't use sqrt()
!
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 :(
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.
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.
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}
function s(n)
.
\$\endgroup\$
lambda x: ...
either, I see solutions like f=lambda x: ...
.
\$\endgroup\$
i`Ad`A^.5
As a function, 15 characters:
i`A:Return A^.5
function s(n){return Math.pow(n,.5)}
AWK, 8
1,$0^=.5
Following solution can handle all values except 0
AWK, 6
$0^=.5
&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+
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:
>+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:
>+>>>>+++++++++++++++<<<<[>>+<+<[->[->->>+<<]>[-<+>>]<+<<]>[-]>[-]<<<[->+>>+<<<]>[-<+>]>>>>[-<+<<<+>>>>]<<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>[-<<<+>>>]<[->>+>+<<<]<[->+>>>>+<<<<<]>+[>>[-<]<[>]<-]>>>+<[[-]>[-]>[-<<<<+>>>>]<<<<<+<+>>>>]>[->[-]<[-<<<+>>>]]<<<[->+<]<<[->>+<<<<->>]<+<[-[+>>>[-]>>[-]<<<<-]>[->>>>>+<<<<]<]>[->]<<]<[-]>>>>>[-<<<<+<+>>>>>]>>[-<<<<<<+>>>>>>]<[-<<<+>>>]<<[-<<+>>]
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[->-[>+>>]>[+[-<+>]>+>>]<<<<<]}
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
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
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.
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
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 ;-)
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/')
}
zsh
too.
\$\endgroup\$
Dec 16, 2013 at 8:31
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 registers1
is the original seedddstlnr/+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
.s=(n)->n**.5
Thanks to gnibbler's post for the .5
idea, I wouldn't have remembered that by myself.
exp(0.5*log(x))
? \$\endgroup\$log
for the base 10 logarithm, so you might tryexp(0.5*ln(x))
to get the natural log orpow10(0.5*log(x))
or similar. \$\endgroup\$