Search code examples
golfscript

How does this GolfScript code print 1000 digits of pi?


How does this code work?

;''
6666,-2%{2+.2/@*\/10.3??2*+}*
`1000<~\;

It seem to use an array @* and a cycle {/**/}, but what is 6666? what is \/?


Solution

  • The first three characters; ;'', are unneeded for the program to function. They simply discard all input and replace it with an empty string, in case your compiler needs an input necessarily.

    6666, prints out an array 6666 elements long, each of which are the numbers 0-6665.

    -2% is a mapping function. It reverses the function and deletes every two elements. You now you have an array that is 3333 elements long, and it goes [6665 6663 6661 … 5 3 1]

    {foo}* is a folding block call. For every element, do the following to the combination of elements. For example, 5,{+}* would add together the numbers 0-4.

    So, let's see what we're doing in this folding block call.

    2+ add two to the element.

    . duplicate the element.

    2/ halve it. Your sub-stack looks like this; (n+2),((n+2)/2)

    @ pulls the third element to the top.

    This is the first function we cannot do, since our original stack is only two tall. We'll get back to this later.

    *\/ will be skipped for now, we'll get back to it once we discuss folding more.

    10.3?? Duplicate 10, then push a 3. [10 10 3]. ? is exponentiation, so we have [10 1000], then again gives us a 1 with 1000 zeroes afterwards.

    2* Multiply it by two. So now we have a 2 with 1000 zeroes after.

    + Adds the rest of our math to 2e(1e3)

    So, let's go back to that pesky @.

    @*\/ will grab the third element and bring it to the top, then multiply it by the next top element ((n+2)/2), then we divide n by this number.

    This is an expansion of the Leibniz Series.

    \`1000< turns the int into a string, then throws a decimal after the 3.

    ~ dumps the string into a number again.

    \; deleted the rest of the stack.

    To answer your specific questions;

    6666 was chosen, since half is 3333 (length of array), and we want more than pi times the number of digits of accuracy we want. We could make it smaller if we wanted, but 6666 is a cute number to use.

    \/ Is the "inverse division" pair. Take a, take b, then calculate b/a. This is because the \ changes the order of the top two elements in the array, and / divides them.