Trova l'ennesimo decimale di pi


33

Ci sono già 30 sfide dedicate al pi ma nessuna ti chiede di trovare l'ennesimo decimale, quindi ...

Sfida

Per qualsiasi numero intero nell'intervallo di 0 <= n <= 10000visualizzazione, l'ennesimo decimale di pi.

Regole

  • I decimali sono ogni numero dopo 3.
  • Il tuo programma può essere una funzione o un programma completo
  • È necessario produrre il risultato in base 10
  • È possibile ottenere nda qualsiasi metodo di input adatto (stdin, input (), parametri di funzione, ...), ma non codificato
  • Puoi utilizzare l' indicizzazione basata su 1 se è nativa nella tua lingua preferita
  • Non avete a che fare con input non valido ( n == -1, n == 'a'o n == 1.5)
  • I builtin sono consentiti, se supportano fino a almeno 10k decimali
  • Il runtime non ha importanza, poiché si tratta del codice più breve e non del codice più veloce
  • Questo è , vince il codice più corto in byte

Casi test

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

Per riferimento, ecco le prime 100k cifre di pi.


Built-in? ad es.str(pi())[n+2]
primo

6
I target duplicati più vicini IMO sono Il calcolo della cifra troncata somma i poteri di pi (sovraccarica il parametro, o sarebbe solo una differenza finita applicata a questa sfida), Trasmetti pi con precisione (aggiunge un indice e sopprime la stampa) e Crittografia della finestra Pi .
Peter Taylor,

3
@Suever ofcourse! Questa regola è solo per sottolineare che 10k è il minimo che il tuo programma dovrebbe essere in grado di gestire
Bassdrop Cumberwubwubwub,

4
Suggerisco di aggiungere f (599) ai casi di test, in quanto può essere facile sbagliare (sono necessari circa 3 decimali di precisione extra).
aditsu,

2
Anche f (760) = 4, che inizia la sequenza 4 999999 8, è facile da arrotondare in modo errato.
Anders Kaseorg,

Risposte:


22

05AB1E, 3 byte

žs¤

spiegato

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

Provalo online

Utilizza l'indicizzazione basata su 1.
Supporta fino a 100k cifre.


Le cifre da pi a n non arrotondano?
busukxuan,

7
@busukxuan No. Ha usato una costante predefinita da pi a 100k cifre e ne recupera N.
Emigna,

4
@Emigna È molto utile. Buona soluzione
Suever,

2
Breve e
acuto

16

Python 2, 66 byte

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

L'input è preso dallo stdin.


Esempio di utilizzo

$ 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

Fai attenzione a usare n nell'algoritmo ... l'output per 599 dovrebbe essere 2, non 1. Inoltre potresti voler specificare che stai usando Python 2.
aditsu

@aditsu aggiornato. Confermato per tutti n ≤ 1000 .
primo

1
Se ritieni che nsia l'input più 9, puoi evitare le parentesi.
xnor

@xnor d'oh. Grazie;)
primo

2
Le prime poche cifre generate da questo algoritmo sono "3.141596535897932 ..." a cui manca un "2" tra i punti 5 e 6. Perché? Perché è allora che l'operatore `` Python 2 '' inizia ad aggiungere un Lalla stringa.
Anders Kaseorg,

11

Bash + coreutils, 60 49 byte

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

Migliorato da Dennis. Thanks!

L'indice è basato su uno.


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.


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

2
Almost every lambda here are anonymous (you can search answers in Python in this site)
Leaky Nun

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

1
You can't run the code directly. It is akin to placing import statements beforehand, just that this makes some global variables beforehand.
Leaky Nun

i=3 while a:a=i/2*a/i;p+=a;i+=2 for 4.
primo

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

@LuisMendo Oh yea I guess the output is already a string. Doh!
Suever

@LuisMendo Oh I never actually thought of that. I always use YP in my testing of the symbolic toolbox
Suever

Is YP actually allowed? The question says it's allowed if it supports <=10k digits
busukxuan

@Suever OP stated "up to" rather than "at least". To my understanding that means supporting >10k is forbidden.
busukxuan

@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

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


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.


1
You need the print call, or else this is a snippet which only works in the REPL.
Mego

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

2
@Mego there aren't "99999" runs?
busukxuan

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: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan

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


4

Mathematica, 23 21 bytes

⌊10^# Pi⌋~Mod~10&

SageMath, 24 bytes

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

@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

Actually it works in the Mathematica Online (I had been using the console version), so I’ll take it, I guess.
Anders Kaseorg

4
These should be separate answers. Though they use the same strategy, they are nowhere near the same language.
Mego

@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

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

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])

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

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


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!


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

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

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 π/2=k=0k!/(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 π/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]

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

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!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.