Find the nth decimal of pi

33

8

There are already 30 challenges dedicated to pi but not a single one asks you to find the nth decimal, so...

Challenge

For any integer in the range of 0 <= n <= 10000 display the nth decimal of pi.

Rules

  • Decimals are every number after 3.
  • Your program may be a function, or a full program
  • You must output the result in base 10
  • You may get n from any suitable input method (stdin, input(), function parameters, ...), but not hardcoded
  • You may use 1-based indexing if that's native to your language of choice
  • You don't have to deal with invalid input (n == -1, n == 'a' or n == 1.5)
  • Builtins are allowed, if they support up to at least 10k decimals
  • Runtime doesn't matter, since this is about the shortest code and not the fastest code
  • This is , shortest code in bytes wins

Test cases

f(0)     == 1
f(1)     == 4 // for 1-indexed languages f(1) == 1
f(2)     == 1 // for 1-indexed languages f(2) == 4
f(3)     == 5
f(10)    == 8
f(100)   == 8
f(599)   == 2
f(760)   == 4
f(1000)  == 3
f(10000) == 5

For reference, here are the first 100k digits of pi.

Bassdrop Cumberwubwubwub

Posted 2016-07-04T13:23:00.717

Reputation: 5 707

Built-ins? e.g. str(pi())[n+2] – primo – 2016-07-04T13:27:07.617

What about this?

– Leaky Nun – 2016-07-04T13:27:23.937

@primo Allowed. This is to find the shortest code in each language – Bassdrop Cumberwubwubwub – 2016-07-04T13:27:40.930

@primo how it is possible to generate an infinite array with codes like pi() and then get the n+2th digit is beyond me. – Leaky Nun – 2016-07-04T13:27:55.267

@LeakyNun Related, but not a dupe imo. – Bassdrop Cumberwubwubwub – 2016-07-04T13:28:03.227

@LeakyNun that's very nearly a valid answer in Sage. – primo – 2016-07-04T13:31:58.383

6

The closest dupe targets IMO are Computing truncated digit sums powers of pi (overloads the parameter, or it would just be a finite difference applied to this challenge), Transmit pi precisely (adds an index and suppresses some printing), and Pi window encryption.

– Peter Taylor – 2016-07-04T13:38:33.750

May we use base 16? – Adám – 2016-07-04T14:01:37.690

@Adám no, the result must be output in base 10 – Bassdrop Cumberwubwubwub – 2016-07-04T14:41:43.337

3@Suever ofcourse! That rule is just to point out that 10k is the minimum that your program should be able to handle – Bassdrop Cumberwubwubwub – 2016-07-04T14:59:13.230

4I suggest adding f(599) to the test cases, as it can be easy to get it wrong (you need about 3 decimals extra precision). – aditsu quit because SE is EVIL – 2016-07-04T16:04:27.337

2

Also f(760) = 4, which begins the sequence 49999998, is easy to round incorrectly.

– Anders Kaseorg – 2016-07-05T04:11:03.993

@aditsu & Anders, edited them in, thanks! – Bassdrop Cumberwubwubwub – 2016-07-05T08:17:59.777

Can we use external files? – OldBunny2800 – 2016-07-22T16:37:49.783

@OldBunny2800 No, sorry. – Bassdrop Cumberwubwubwub – 2016-07-22T16:54:52.920

Answers

22

05AB1E, 3 bytes

žs¤

Explained

žs   # push pi to N digits
  ¤  # get last digit

Try it online

Uses 1-based indexing.
Supports up to 100k digits.

Emigna

Posted 2016-07-04T13:23:00.717

Reputation: 50 798

Pi to n digits doesn't round? – busukxuan – 2016-07-04T16:13:39.447

7@busukxuan No. It used a predefined constant of pi to 100k digits and retrieves N of them. – Emigna – 2016-07-04T16:48:27.853

4@Emigna That is very handy. Good solution. – Suever – 2016-07-04T17:10:08.317

2Short and Sharp, PCG at its best – Xylius – 2016-07-05T05:14:25.097

16

Python 2, 66 bytes

n=input()+9
x=p=5L**7
while~-p:x=p/2*x/p+10**n;p-=2
print`x/5`[-9]

Input is taken from stdin.


Sample Usage

$ echo 10 | python pi-nth.py
8

$ echo 100 | python pi-nth.py
8

$ echo 1000 | python pi-nth.py
3

$ echo 10000 | python pi-nth.py
5

primo

Posted 2016-07-04T13:23:00.717

Reputation: 30 891

Be careful about using n in the algorithm... output for 599 should be 2, not 1. Also you may want to specify that you're using python 2. – aditsu quit because SE is EVIL – 2016-07-04T16:01:01.523

@aditsu updated. Confirmed for all n ≤ 1000. – primo – 2016-07-04T16:57:10.693

1If you take n to be the input plus 9, you can avoid parens. – xnor – 2016-07-04T23:48:39.640

@xnor d'oh. Thanks ;) – primo – 2016-07-05T00:45:59.307

2The first few digits generated by this algorithm are ‘3.141596535897932…’ which is missing a ‘2’ between places 5 and 6. Why? Because that’s when Python 2’s `` operator starts appending an L to the string. – Anders Kaseorg – 2016-07-05T03:37:42.010

@AndersKaseorg The L is present in the very first iteration - demo. True for both 32 and 64-bit versions of CPython.

– primo – 2016-07-05T04:27:07.237

@primo That is not what I get on 64-bit CPython (I tried 2.3.7, 2.4.6, 2.5.6, 2.6.9, 2.7.6, and 2.7.12), but I’ll accept that it works on 32-bit CPython. – Anders Kaseorg – 2016-07-05T05:30:26.857

@AndersKaseorg you're right, 64-bit on Linux did have an issue. Should now be correct. – primo – 2016-07-05T05:53:37.363

11

Bash + coreutils, 60 49 bytes

echo "scale=10100;4*a(1)"|bc -l|tr -d '\\\n'|cut -c$(($1+2))

bc -l<<<"scale=$1+9;4*a(1)-3"|tr -dc 0-9|cut -c$1

Improved by Dennis. Thanks!

The index is one-based.

Marco

Posted 2016-07-04T13:23:00.717

Reputation: 581

11

Python 2, 73 71 73 bytes

thanks to @aditsu for increasing my score by 2 bytes

Finally an algorithm that can complete under 2 seconds.

n=10**10010
a=p=2*n
i=1
while a:a=a*i/(2*i+1);p+=a;i+=1
lambda n:`p`[n+1]

Ideone it!

Uses the formula pi = 4*arctan(1) while computing arctan(1) using its taylor series.

Leaky Nun

Posted 2016-07-04T13:23:00.717

Reputation: 45 011

Quite speedy. 1-indexing is not native to python, though. Last I recall (admittedly I've been inactive for a while), consensus was that functions need to be defined, e.g. f=lambda n:.... – primo – 2016-07-04T17:14:12.273

2Almost every lambda here are anonymous (you can search answers in Python in this site) – Leaky Nun – 2016-07-04T17:16:06.523

Relevant meta post. Seems to be in violation of Rule 1 and 3 (after running your code, there is no way to capture the function reference; the function definition would need to be typed out for each input ((lambda n:`p`[n+1])(1), (lambda n:`p`[n+1])(2), ...). – primo – 2016-07-04T17:27:08.050

1You can't run the code directly. It is akin to placing import statements beforehand, just that this makes some global variables beforehand. – Leaky Nun – 2016-07-04T17:34:04.767

i=3 while a:a=i/2*a/i;p+=a;i+=2 for 4. – primo – 2016-07-04T17:43:49.317

@primo that looks like your answer xd – Leaky Nun – 2016-07-04T17:48:10.443

Same alg: Leibniz Series (derived from arctan(1)), Euler Transform (Appendix A). Counting backwards is self-correcting, and slightly shorter.

– primo – 2016-07-04T17:55:27.810

7

MATL, 11 10 bytes

1 byte saved thanks to @Luis

YPiEY$GH+)

This solution utilizes 1-based indexing

Try it Online

All test cases

Explanation

YP  % Pre-defined literal for pi
iE  % Grab the input and multiply by 2 (to ensure we have enough digits to work with)
Y$  % Compute the first (iE) digits of pi and return as a string
G   % Grab the input again
H+  % Add 2 (to account for '3.') in the string
)   % And get the digit at that location
    % Implicitly display the result

Suever

Posted 2016-07-04T13:23:00.717

Reputation: 10 257

@LuisMendo Oh yea I guess the output is already a string. Doh! – Suever – 2016-07-04T14:38:20.587

@LuisMendo Oh I never actually thought of that. I always use YP in my testing of the symbolic toolbox – Suever – 2016-07-04T14:40:11.783

Is YP actually allowed? The question says it's allowed if it supports <=10k digits – busukxuan – 2016-07-04T14:50:37.747

@Suever OP stated "up to" rather than "at least". To my understanding that means supporting >10k is forbidden. – busukxuan – 2016-07-04T14:54:46.310

@Suever Yeah, I think I may be, tho I can't resist doing it lol. I deleted my Sage answer just because of that. – busukxuan – 2016-07-04T14:57:27.030

@Suever Oh nice! I'll un-delete it :-) – busukxuan – 2016-07-04T15:00:35.560

6

Mathematica 30 bytes

RealDigits[Pi,10,1,-#][[1,1]]&

f=%

f@0
f@1
f@2
f@3
f@10
f@100
f@599
f@760
f@1000
f@10000

1
4
1
5
8
8
2
4
3
5

DavidC

Posted 2016-07-04T13:23:00.717

Reputation: 24 524

5

Sage, 32 25 bytes

lambda d:`n(pi,9^5)`[d+2]

My first answer in a language of this kind.

n rounds pi to 17775 digits.

busukxuan

Posted 2016-07-04T13:23:00.717

Reputation: 2 728

1You need the print call, or else this is a snippet which only works in the REPL. – Mego – 2016-07-05T01:24:12.677

This works for (theoretically) any input: lambda d:\n(pi,digits=d+5)`[-4]`

– Mego – 2016-07-05T01:37:46.973

2@Mego there aren't "99999" runs? – busukxuan – 2016-07-05T01:43:35.783

@Mego busukxuan is right, that fails as early as 760, 761, 762, 763. – Anders Kaseorg – 2016-07-05T03:51:54.527

Then bump up the extra digits: lambda d:\n(pi,digits=d+9)`[-8]`

– Mego – 2016-07-05T06:39:43.220

1

@Mego but then there will be even longer "9" runs. I'm not sure if doubling the length can make it universal, but I think not even that can do it, due to the Infinite Monkey Theorem: https://en.wikipedia.org/wiki/Infinite_monkey_theorem

– busukxuan – 2016-07-05T15:00:07.610

1@busukxuan If you model the uncomputed digits of π as random, you certainly expect arbitrarily long runs of 9s (and we have no reason to expect the real π to be any different, though we have not proven this), but you only expect a run of 9s as long as its position with vanishingly small probability (though again, we haven’t proven that the real π doesn’t behave unexpectedly). We have found runs of at least nine 9s, which I think is enough to break the [-8] proposal. – Anders Kaseorg – 2016-07-05T18:09:54.117

4

CJam, 32

7e4,-2%{2+_2/@*\/2e10005+}*sq~)=

Try it online (it's a bit slow)

aditsu quit because SE is EVIL

Posted 2016-07-04T13:23:00.717

Reputation: 22 326

4

Mathematica, 23 21 bytes

⌊10^# Pi⌋~Mod~10&

SageMath, 24 bytes

lambda n:int(10^n*pi)%10

Anders Kaseorg

Posted 2016-07-04T13:23:00.717

Reputation: 29 242

@LLlAMnYP I tried that, but Mathematica seems to require a space between Pi and (or between # and if the multiplication is flipped), so the saving disappears. – Anders Kaseorg – 2016-07-05T09:59:41.927

Actually it works in the Mathematica Online (I had been using the console version), so I’ll take it, I guess. – Anders Kaseorg – 2016-07-05T10:12:46.697

4These should be separate answers. Though they use the same strategy, they are nowhere near the same language. – Mego – 2016-07-05T10:45:13.003

@Mego The policy I found does not say answers in different languages cannot count as very similar. (The answer suggesting that was not accepted.) Are you referring to another policy or just a preference?

– Anders Kaseorg – 2016-07-05T17:48:43.300

3

Clojure, 312 bytes

(fn[n](let[b bigdec d #(.divide(b %)%2(+ n 4)BigDecimal/ROUND_HALF_UP)m #(.multiply(b %)%2)a #(.add(b %)%2)s #(.subtract % %2)](-(int(nth(str(reduce(fn[z k](a z(m(d 1(.pow(b 16)k))(s(s(s(d 4(a 1(m 8 k)))(d 2(a 4(m 8 k))))(d 1(a 5(m 8 k))))(d 1(a 6(m 8 k)))))))(bigdec 0)(map bigdec(range(inc n)))))(+ n 2)))48)))48)))

So, as you can probably tell, I have no idea what I'm doing. This ended up being more comical than anything. I Google'd "pi to n digits", and ended up on the Wikipedia page for the Bailey–Borwein–Plouffe formula. Knowing just barely enough Calculus(?) to read the formula, I managed to translate it into Clojure.

The translation itself wasn't that difficult. The difficulty came from handling precision up to n-digits, since the formula requires (Math/pow 16 precision); which gets huge really fast. I needed to use BigDecimal everywhere for this to work, which really bloated things up.

Ungolfed:

(defn nth-pi-digit [n]
  ; Create some aliases to make it more compact
  (let [b bigdec
        d #(.divide (b %) %2 (+ n 4) BigDecimal/ROUND_HALF_UP)
        m #(.multiply (b %) %2)
        a #(.add (b %) %2)
        s #(.subtract % %2)]
    (- ; Convert the character representation to a number...
      (int ; by casting it using `int` and subtracting 48
         (nth ; Grab the nth character, which is the answer
           (str ; Convert the BigDecimal to a string
             (reduce ; Sum using a reduction
               (fn [sum k]
                 (a sum ; The rest is just the formula
                       (m
                         (d 1 (.pow (b 16) k))
                         (s
                           (s
                             (s
                               (d 4 (a 1 (m 8 k)))
                               (d 2 (a 4 (m 8 k))))
                             (d 1 (a 5 (m 8 k))))
                           (d 1 (a 6 (m 8 k)))))))
               (bigdec 0)
               (map bigdec (range (inc n))))) ; Create an list of BigDecimals to act as k
           (+ n 2)))
      48)))

Needless to say, I'm sure there's an easier way to go about this if you know any math.

(for [t [0 1 2 3 10 100 599 760 1000 10000]]
  [t (nth-pi-digit t)])

([0 1] [1 4] [2 1] [3 5] [10 8] [100 8] [599 2] [760 4] [1000 3] [10000 5])

Carcigenicate

Posted 2016-07-04T13:23:00.717

Reputation: 3 295

I realized later that the standard operators actually work on big decimals, so the shortcuts at the top are unnecessary. I mount fix this at some point. That'll probably knock off ~50 bytes. – Carcigenicate – 2019-06-07T15:08:09.007

3

J, 19 15 bytes

10([|<.@o.@^)>:

Takes an integer n and outputs the nth digit of pi. Uses zero-based indexing. To get the nth digit, compute pi times 10n+1, take the floor of that value, and then take it modulo 10.

Usage

The input is an extended integer.

   f =: 10([|<.@o.@^)>:
   (,.f"0) x: 0 1 2 3 10 100 599 760 1000
   0 1
   1 4
   2 1
   3 5
  10 8
 100 8
 599 2
 760 4
1000 3
   timex 'r =: f 10000x'
1100.73
   r
5

On my machine, it takes about 18 minutes to compute the 10000th digit.

Explanation

10([|<.@o.@^)>:  Input: n
             >:  Increment n
10               The constant n
           ^     Compute 10^(n+1)
        o.@      Multiply by pi
     <.@         Floor it
   [             Get 10
    |            Take the floor modulo 10 and return

miles

Posted 2016-07-04T13:23:00.717

Reputation: 15 654

2

Python 3, 338 bytes

This implementation is based on the Chudnovsky algorithm, one of the fastest algorithms to estimate pi. For each iteration, roughly 14 digits are estimated (take a look here for further details).

f=lambda n,k=6,m=1,l=13591409,x=1,i=0:not i and(exec('global d;import decimal as d;d.getcontext().prec=%d'%(n+7))or str(426880*d.Decimal(10005).sqrt()/f(n//14+1,k,m,l,x,1))[n+2])or i<n and d.Decimal(((k**3-16*k)*m//i**3)*(l+545140134))/(x*-262537412640768000)+f(n,k+12,(k**3-16*k)*m

Try it online!

PieCot

Posted 2016-07-04T13:23:00.717

Reputation: 1 039

2

Clojure, 253 bytes

(defmacro q[& a] `(with-precision ~@a))(defn h[n](nth(str(reduce +(map #(let[p(+(* n 2)1)a(q p(/ 1M(.pow 16M %)))b(q p(/ 4M(+(* 8 %)1)))c(q p(/ 2M(+(* 8 %)4)))d(q p(/ 1M(+(* 8 %)5)))e(q p(/ 1M(+(* 8 %)6)))](* a(-(-(- b c)d)e)))(range(+ n 9)))))(+ n 2)))

Calculate number pi using this formula. Have to redefine macro with-precision as it's used too frequently.

You can see the output here: https://ideone.com/AzumC3 1000 and 10000 takes exceeds time limit used on ideone, shrugs

cliffroot

Posted 2016-07-04T13:23:00.717

Reputation: 1 080

1

Smalltalk – 270 bytes

Relies on the identity tan⁻¹(x) = x − x³/3 + x⁵/5 − x⁷/7 ..., and that π = 16⋅tan⁻¹(1/5) − 4⋅tan⁻¹(1/239). SmallTalk uses unlimited precision integer arithmetic so it will work for large inputs, if you're willing to wait!

|l a b c d e f g h p t|l:=stdin nextLine asInteger+1. a:=1/5. b:=1/239. c:=a. d:=b. e:=a. f:=b. g:=3. h:=-1. l timesRepeat:[c:=c*a*a. d:=d*b*b. e:=h*c/g+e. f:=h*d/g+f. g:=g+2. h:=0-h]. p:=4*e-f*4. l timesRepeat:[t:=p floor. p:=(p-t)*10]. Transcript show:t printString;cr

Save as pi.st and run as in the following test cases. Indexing is one based.

$ gst -q pi.st <<< 1
1
$ gst -q pi.st <<< 2
4
$ gst -q pi.st <<< 3
1
$ gst -q pi.st <<< 4
5
$ gst -q pi.st <<< 11
8
$ gst -q pi.st <<< 101
8
$ gst -q pi.st <<< 600
2
$ gst -q pi.st <<< 761
4
$ gst -q pi.st <<< 1001
3
$ gst -q pi.st <<< 10001 -- wait a long time!
5

user15259

Posted 2016-07-04T13:23:00.717

Reputation:

1

JavaScript (Node.js) (Chrome 67+), 75 73 67 63 bytes

n=>`${eval(`for(a=c=100n**++n*20n,d=1n;a*=d;)c+=a/=d+++d`)}`[n]

Try it online!

Using \$\pi/2=\sum_{k=0}^{\infty}k!/(2k+1)!!\$ (same logic used by Leaky Nun's Python answer, but thanks to the syntax of JS that makes this shorter). Input is passed to the function as a BigInt. 2 bytes can be removed if 1-based indexing is used:

n=>`${eval(`for(a=c=100n**n*20n,d=1n;a*=d;)c+=a/=d+++d`)}`[n]

JavaScript (Node.js) (Chrome 67+), 90 89 bytes

n=>`${eval(`for(a=100n**++n*2n,b=a-a/3n,c=0n,d=1n;w=a+b;a/=-4n,b/=-9n,d+=2n)c+=w/d`)}`[n]

Try it online!

Using \$\pi/4=\arctan(1/2)+\arctan(1/3)\$. Input is passed to the function as a BigInt. 2 bytes can be removed if 1-based indexing is used:

n=>`${eval(`for(a=100n**n*2n,b=a-a/3n,c=0n,d=1n;w=a+b;a/=-4n,b/=-9n,d+=2n)c+=w/d`)}`[n]

Shieru Asakoto

Posted 2016-07-04T13:23:00.717

Reputation: 4 445

1

Java 7, 262 260 bytes

import java.math.*;int c(int n){BigInteger p,a=p=BigInteger.TEN.pow(10010).multiply(new BigInteger("2"));for(int i=1;a.compareTo(BigInteger.ZERO)>0;p=p.add(a))a=a.multiply(new BigInteger(i+"")).divide(new BigInteger((2*i+++1)+""));return(p+"").charAt(n+1)-48;}

Used @LeakyNun's Python 2 algorithm.

Ungolfed & test code:

Try it here.

import java.math.*;
class M{
  static int c(int n){
    BigInteger p, a = p = BigInteger.TEN.pow(10010).multiply(new BigInteger("2"));
    for(int i = 1; a.compareTo(BigInteger.ZERO) > 0; p = p.add(a)){
      a = a.multiply(new BigInteger(i+"")).divide(new BigInteger((2 * i++ + 1)+""));
    }
    return (p+"").charAt(n+1) - 48;
  }

  public static void main(String[] a){
    System.out.print(c(0)+", ");
    System.out.print(c(1)+", ");
    System.out.print(c(2)+", ");
    System.out.print(c(3)+", ");
    System.out.print(c(10)+", ");
    System.out.print(c(100)+", ");
    System.out.print(c(599)+", ");
    System.out.print(c(760)+", ");
    System.out.print(c(1000)+", ");
    System.out.print(c(10000));
  }
}

Output:

1, 4, 1, 5, 8, 8, 2, 4, 3, 5

Kevin Cruijssen

Posted 2016-07-04T13:23:00.717

Reputation: 67 575

0

C#, 252 250 bytes

d=>{int l=(d+=2)*10/3+2,j=0,i=0;long[]x=new long[l],r=new long[l];for(;j<l;)x[j++]=20;long c,n,e,p=0;for(;i<d;++i){for(j=0,c=0;j<l;c=x[j++]/e*n){n=l-j-1;e=n*2+1;r[j]=(x[j]+=c)%e;}p=x[--l]/10;r[l]=x[l++]%10;for(j=0;j<l;)x[j]=r[j++]*10;}return p%10+1;}

Try it online!

TheLethalCoder

Posted 2016-07-04T13:23:00.717

Reputation: 6 930

0

Maple, 24 bytes

 trunc(10^(n+1)*Pi)mod 10

Test cases:

> f:=n->trunc(10^(n+1)*Pi)mod 10;
> f(0);
  1
> f(1);
  4
> f(2);
  1
> f(3);
  5
> f(10);
  8
> f(100);
  8
> f(599);
  2
> f(760);
  4
> f(1000);
  3
> f(10000);
  5

DSkoog

Posted 2016-07-04T13:23:00.717

Reputation: 560