33
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Built-ins? e.g. str(pi())[n+2] \$\endgroup\$ – primo Jul 4 '16 at 13:27
  • 6
    \$\begingroup\$ 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. \$\endgroup\$ – Peter Taylor Jul 4 '16 at 13:38
  • 3
    \$\begingroup\$ @Suever ofcourse! That rule is just to point out that 10k is the minimum that your program should be able to handle \$\endgroup\$ – Bassdrop Cumberwubwubwub Jul 4 '16 at 14:59
  • 4
    \$\begingroup\$ I suggest adding f(599) to the test cases, as it can be easy to get it wrong (you need about 3 decimals extra precision). \$\endgroup\$ – aditsu Jul 4 '16 at 16:04
  • 2
    \$\begingroup\$ Also f(760) = 4, which begins the sequence 49999998, is easy to round incorrectly. \$\endgroup\$ – Anders Kaseorg Jul 5 '16 at 4:11

18 Answers 18

22
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Pi to n digits doesn't round? \$\endgroup\$ – busukxuan Jul 4 '16 at 16:13
  • 7
    \$\begingroup\$ @busukxuan No. It used a predefined constant of pi to 100k digits and retrieves N of them. \$\endgroup\$ – Emigna Jul 4 '16 at 16:48
  • 4
    \$\begingroup\$ @Emigna That is very handy. Good solution. \$\endgroup\$ – Suever Jul 4 '16 at 17:10
  • 2
    \$\begingroup\$ Short and Sharp, PCG at its best \$\endgroup\$ – Xylius Jul 5 '16 at 5:14
16
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – aditsu Jul 4 '16 at 16:01
  • \$\begingroup\$ @aditsu updated. Confirmed for all n ≤ 1000. \$\endgroup\$ – primo Jul 4 '16 at 16:57
  • 1
    \$\begingroup\$ If you take n to be the input plus 9, you can avoid parens. \$\endgroup\$ – xnor Jul 4 '16 at 23:48
  • \$\begingroup\$ @xnor d'oh. Thanks ;) \$\endgroup\$ – primo Jul 5 '16 at 0:45
  • 2
    \$\begingroup\$ The 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. \$\endgroup\$ – Anders Kaseorg Jul 5 '16 at 3:37
11
\$\begingroup\$

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.

\$\endgroup\$
11
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 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:.... \$\endgroup\$ – primo Jul 4 '16 at 17:14
  • 2
    \$\begingroup\$ Almost every lambda here are anonymous (you can search answers in Python in this site) \$\endgroup\$ – Leaky Nun Jul 4 '16 at 17:16
  • \$\begingroup\$ 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), ...). \$\endgroup\$ – primo Jul 4 '16 at 17:27
  • 1
    \$\begingroup\$ You can't run the code directly. It is akin to placing import statements beforehand, just that this makes some global variables beforehand. \$\endgroup\$ – Leaky Nun Jul 4 '16 at 17:34
  • \$\begingroup\$ i=3 while a:a=i/2*a/i;p+=a;i+=2 for 4. \$\endgroup\$ – primo Jul 4 '16 at 17:43
7
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ @LuisMendo Oh yea I guess the output is already a string. Doh! \$\endgroup\$ – Suever Jul 4 '16 at 14:38
  • \$\begingroup\$ @LuisMendo Oh I never actually thought of that. I always use YP in my testing of the symbolic toolbox \$\endgroup\$ – Suever Jul 4 '16 at 14:40
  • \$\begingroup\$ Is YP actually allowed? The question says it's allowed if it supports <=10k digits \$\endgroup\$ – busukxuan Jul 4 '16 at 14:50
  • \$\begingroup\$ @Suever OP stated "up to" rather than "at least". To my understanding that means supporting >10k is forbidden. \$\endgroup\$ – busukxuan Jul 4 '16 at 14:54
  • \$\begingroup\$ @Suever Yeah, I think I may be, tho I can't resist doing it lol. I deleted my Sage answer just because of that. \$\endgroup\$ – busukxuan Jul 4 '16 at 14:57
6
\$\begingroup\$

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

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

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ You need the print call, or else this is a snippet which only works in the REPL. \$\endgroup\$ – Mego Jul 5 '16 at 1:24
  • \$\begingroup\$ This works for (theoretically) any input: lambda d:`n(pi,digits=d+5)`[-4] \$\endgroup\$ – Mego Jul 5 '16 at 1:37
  • 2
    \$\begingroup\$ @Mego there aren't "99999" runs? \$\endgroup\$ – busukxuan Jul 5 '16 at 1:43
  • 1
    \$\begingroup\$ @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: en.wikipedia.org/wiki/Infinite_monkey_theorem \$\endgroup\$ – busukxuan Jul 5 '16 at 15:00
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – Anders Kaseorg Jul 5 '16 at 18:09
4
\$\begingroup\$

CJam, 32

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

Try it online (it's a bit slow)

\$\endgroup\$
4
\$\begingroup\$

Mathematica, 23 21 bytes

⌊10^# Pi⌋~Mod~10&

SageMath, 24 bytes

lambda n:int(10^n*pi)%10
\$\endgroup\$
  • \$\begingroup\$ @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. \$\endgroup\$ – Anders Kaseorg Jul 5 '16 at 9:59
  • \$\begingroup\$ Actually it works in the Mathematica Online (I had been using the console version), so I’ll take it, I guess. \$\endgroup\$ – Anders Kaseorg Jul 5 '16 at 10:12
  • 4
    \$\begingroup\$ These should be separate answers. Though they use the same strategy, they are nowhere near the same language. \$\endgroup\$ – Mego Jul 5 '16 at 10:45
  • \$\begingroup\$ @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? \$\endgroup\$ – Anders Kaseorg Jul 5 '16 at 17:48
3
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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])
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Carcigenicate Jun 7 at 15:08
2
\$\begingroup\$

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

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

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!

\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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]
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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