XP is just a number PerlMonks

### Golf -- compute PI

by Ovid (Cardinal)
 on Apr 16, 2002 at 00:18 UTC Need Help??

A friend was talking about computing PI, so wrote this script to compute it.

```#!/usr/bin/perl -w
#Compute pi. Based on Leibniz's algorithm that
#       pi = 4 - 4/3 + 4/5 - 4/7 + 4/9 - 4/11...
use strict;

my \$pi = 4;
my \$next_digits = get_leibniz();

for ( 1 .. 100000 ) {
my ( \$subtract, \$add ) =  &\$next_digits;
\$pi = \$pi - \$subtract + \$add;
}

print \$pi;

sub get_leibniz {
my \$index = 1;
my \$sub = sub {
\$index += 2;
my \$first = 4/\$index;
\$index += 2;
my \$second = 4/\$index;
return (\$first, \$second);
};
return \$sub;
}

I can reduce that down to this:

```\$p=4;\$n=l();for(1..100000){(\$s,\$a)=&\$n;\$p=\$p-\$s+\$a}print\$p;
sub l{\$i=1;sub{\$i+=2;\$f=4/\$i;\$i+=2;\$q=4/\$i;(\$f,\$q)}}

112 strokes. Admittedly, I'm rotten at golf. Any takers? No trig functions allowed :)

Update: I took four strokes off by eliminating a space and three superfluous semi-colons. Also, my answer is only correct to 5 digits. I could increase the second value in the for range, but that takes too long. Hadn't really thought about dealing with accuracy. Hmm...

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Replies are listed 'Best First'.
Re: Golf -- compute PI
by japhy (Canon) on Apr 16, 2002 at 01:42 UTC
Here's code that comes in at 49 chars:
```\$i=1;map\$@+=4/(\$i+=4)-4/(\$i-2),0..99999;print\$@+4

_____________________________________________________
Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a (from-home) job
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Golf -- compute PI
by wog (Curate) on Apr 16, 2002 at 02:01 UTC
```\$i+=1/((\$_+=1e-7)**2+1)until\$_>1;print\$i/1e7*4
#23456789_123456789_123456789_123456789_123456
#        1         2         3         4

46 chars. (Changes the algorithm.) Change all 7s to a higher number for a better approximation and slower runtime, change it to a lower number for worse approximation and faster runtime.

update:

```\$i+=(\$_&1?4:-4)/(\$_*2-1)for 1..1e6;print\$i
#23456789_123456789_123456789_123456789_12
#        1         2         3         4

(another, similar solution was there breifly: 44 chars.Pretty much the same algorithm Ovid gave. (The 4 is just factored out.))

42 chars. The same algorithm Ovid gave. (Change the 6 to a higher number for a better approximation, etc.)

Shave another
```\$i+=(\$_%2*8-4)/(\$_*2-1)for 1..1e6;print\$i
or equivalently
```\$i+=4*(-1)**\$_/(1-\$_*2)for 1..1e6;print\$i
Re: Golf -- compute PI
by andreychek (Parson) on Apr 16, 2002 at 04:05 UTC
Here's a few more methods of achieving pi:

# 39 Characters
map\$x+=(-1)**\$_*4/(2*\$_+1),0..1e6;die\$x

Now, I know Ovid said no Trig functions, but I couldn't resist. Perhaps we could consider the next two examples mulligans :-)

# 45 Characters
use Math::Trig;die 16*atan(1/5)-4*atan(1/239)

# 21 Characters
use Math::Trig;die pi

-Eric

Update: Taking some of PrakashK's suggestions, shaved off a few more characters. Thanks PrakashK! :-)
# 23 Characters
use Math::Trig;warn pi;
Why warn, when you can die saving one more character?
```# 22 Characters
use Math::Trig;die pi;
And, you can shave one more character, if you don't care for that pesky semi-colon at the end.

Oh, never mind. We are not supposed to use trig functions.

/prakash

You can get the same result with 20 chars:
```die 3.14159265358979
```
I found this trick in Logique, informatique et paradoxes, publisher Belin (Pour la Science), page 67, it was about the shorter program to get (not compute) pi with n digits.
17 chars, if you're using trig:  ```print 4*atan2 1,1 [download]```
```   MeowChow
s aamecha.s a..a\u\$&owag.print```
```print atan2 0,-1
(MeowChow) Re: Golf -- compute PI
by MeowChow (Vicar) on Apr 16, 2002 at 06:21 UTC
36, obfuscated :)  ```sub _{\$---&&4/\$----&_}print- _\$-=1e5 [download]```
35, but emits a warning:  ```sub _{\$---&&4/\$----&_}print-_\$-=1e5 [download]```
```   MeowChow
s aamecha.s a..a\u\$&owag.print```
Re: Golf -- compute PI
by metadoktor (Hermit) on Apr 16, 2002 at 02:53 UTC
Hmmm....25 char pi with accuracy up to 15 digits...does this count? Just kidding. Ha ha ;)

```sub pi
{
#         1         2
#1234567890123456789012345
print"3.14159265358979\n";
}

Actually, I think it is a little tricky to devise a Perl program that accurately calculates pi. A monk once made this post that seemed to inaccurately calculate pi.

"The doktor is in."

Re: Golf -- compute PI
by belg4mit (Prior) on Apr 16, 2002 at 03:42 UTC
Yes, ignoring accuracy I could win with \$p=22/7; or in some states \$p=3; :-D Oh come on, somebody had to say it.

--
perl -pe "s/\b;([mnst])/'\1/mg"

Re: Golf -- compute PI
by lhoward (Vicar) on Apr 16, 2002 at 01:39 UTC
Here's my entry at 79 bytes. This is admittedly my first golf, so can probably stand some improvement.... It uses a probablistic method for determining pi. As tested below its usually accurate to 2 or 3 decimal places, but is sometimes worse. Accuracy can be increased by increasing the number of iterations.
```for(1..999999){\$x=rand();\$y=rand();\$k++if sqrt(\$x*\$x+\$y*\$y)<1}print 4*
+\$k/999999
I managed to get it down to 61 bytes.... I'm still humbled by some of the other submissions....
```for(1..1e6){\$k++if sqrt(rand()**2+rand()**2)<1}print \$k*4/1e6
Re: Golf -- compute PI
by jsprat (Curate) on Apr 16, 2002 at 01:55 UTC

I'm assuming the algorithm can't be changed.
I just got rid of the neat closure and built it all in the loop. It's got the same five digits of accuracy. The same 72 strokes can have up to a whopping 6 digits of accuracy if you change the 100_000 to 999_999!

Re: Golf -- compute PI (boo)
by boo_radley (Parson) on Apr 16, 2002 at 02:06 UTC
An apparent 67.
```#000000001111111111222222222233333333334444444444555555555566666666
#234567890123456789012345678901234567890123456789012345678901234567
\$i=43;\$p=1;eval'\$x'.chr(\$i).'=4/\$p;\$p+=2;\$i^=6'for 1..10**5;print\$x
update :
```#0000000011111111112222222222333333333344444444445555555555
#2345678901234567890123456789012345678901234567890123456789
\$o=1;\$t=3;for(1..1e5){\$e+=(4/\$o)-(4/\$t);\$o+=4;\$t+=4}print\$e

Simplify, simplify... :)
update :
to Chmrr : (1**5) yeah, I saw that in another solution and felt rather sheepish. As to the exact value of the number, I felt it appropriate to use something approximate to Ovid's original algorithm.

1e5 is shorter than 10**5. This applies equally to all of the solutions given so far. However, as this number only defines the accuracy of the answer, it is arguable that the length of this number should not be counted towards the total par for the answer..

perl -pe '"I lo*`+\$^X\$\"\$]!\$/"=~m%(.*)%s;\$_=\$1;y^`+*^e v^#\$&V"+@( NO CARRIER'

Another "short than 10**5" option is to use a..eqxe instead.

_____________________________________________________
Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a (from-home) job
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Golf -- compute PI
by thospel (Hermit) on Mar 15, 2006 at 03:04 UTC
Pi to 1000 digits: 77 strokes, by tybalt89 with a minor change by ton:
```(\$c,@0)=map P|(\$c=\$c%(\$d=10+20*\$?).0+\$_*\$?)/\$d,@0while\$?-=@0[0,1e3]=3;
+print@0

78 strokes by ton:

```print!s!\w+!\$\=(\$z=\$&.0+\$?--*\$\)/++(\$b=2*\$?||239)|0;\$z%\$b!egfor(-48x65
+536)x1e3

Both can be extended for more digits

Re: Golf -- compute PI
by I0 (Priest) on Apr 17, 2002 at 16:14 UTC
```use integer;\$|++;my@e=(1)x5e3;for(a..zzz){\$e[\$_-1]+=\$e[\$_]/\$_,\$e[\$_]%=
+\$_
for reverse 1..\$#e;print\$e[0];\$e[0]=0;\$_*=10for@e;}
Compute e to 1000 digits, 69 chars
```s!\w+!\$%=(\$z=\$&.0+\$%)/(\$a=--\$?||10);\$z%\$a!eg,print\$%for(-1x65536)x1e3
Re: Golf -- compute PI
by pepik_knize (Scribe) on Apr 16, 2002 at 15:54 UTC
Here's one using Archimedes's method that comes in at 67:

\$n=3;\$s=1;for(1..9){\$n*=2;\$s=(2-(4-\$s**2)**.5)**.5;\$p=\$n*\$s}print\$p

As a side note, I had \$_ instead of \$p inside the curlies, but using just print outside didn't work, and I don't know why.

Pepik

Using \$_ instead of \$p is a nice try to save two strokes, but it fails because for(1..9){..} aliases elements of the range to \$_, which overwrites your later use of \$p. Good job, though.

Cheers,
Ovid

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

You could use \$\ instead, which will trim the two chars at the expense of an 'uninitialized' warning....
```\$n=3;\$s=1;for(1..9){\$n*=2;\$s=(2-(4-\$s**2)**.5)**.5;\$\=\$n*\$s}print
Infact, if you rearrange things and toss in a little obfu, you can trim a few more chars. It even has the side-effect of making it strict compliant:
```\$@=3;\$;=1;\$@*=2,\$;=(2-(4-\$;**2)**.5)**.5,\$\=\$@*\$;for 1..9;print

-Blake

Re: Golf -- compute PI
by Dr. Mu (Hermit) on Apr 22, 2002 at 07:00 UTC
Here's a Monte Carlo prog that weighs in at 42:
```die grep(rand()**2+rand()**2<1,1..4e6)/1e6
(I don't claim it's pretty, converges fast, scrimps on memory, or produces repeatable results.)

Create A New User
Node Status?
node history
Node Type: perlmeditation [id://159377]
Approved by ChemBoy
help
Chatterbox?
 [Corion]: Mhrrrr. Some project made changes to a report I ingest. I tell them "the format of the new rows is bad". They change it, without understanding/ knowing what other systems might act on this suffix. While it now works for me, I'm not really happy with ... [Corion]: ... their approach to changing things and waiting who screams at them.

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (11)
As of 2017-07-24 14:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
I came, I saw, I ...

Results (354 votes). Check out past polls.