Finden Sie die n-te Dezimalstelle von pi

33

Es gibt bereits 30 Herausforderungen für pi, aber keine einzige fordert Sie auf, die n-te Dezimalstelle zu finden, also ...

Herausforderung

Für eine beliebige Ganzzahl im 0 <= n <= 10000Anzeigebereich die n-te Dezimalstelle von pi.

Regeln

  • Nachkommastellen stehen für jede Zahl 3.
  • Ihr Programm kann eine Funktion oder ein vollständiges Programm sein
  • Sie müssen das Ergebnis in Basis 10 ausgeben
  • Sie können njede geeignete Eingabemethode (stdin, input (), Funktionsparameter, ...) verwenden, die jedoch nicht fest codiert ist
  • Sie können die 1-basierte Indizierung verwenden, wenn dies in der Sprache Ihrer Wahl der Fall ist
  • Sie müssen nicht mit ungültigen Eingaben umgehen ( n == -1, n == 'a'oder n == 1.5)
  • Builtins sind zulässig, wenn sie mindestens 10.000 Dezimalstellen unterstützen
  • Die Laufzeit spielt keine Rolle, da es sich um den kürzesten und nicht um den schnellsten Code handelt
  • Dies ist , der kürzeste Code in Bytes gewinnt

Testfälle

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

Als Referenz sind hier die ersten 100k Stellen von pi.

Bassdrop Cumberwubwubwub
quelle
Eingebaute? egstr(pi())[n+2]
primo
6
Die nächsten doppelten Ziele IMO sind die Berechnung der abgeschnittenen Ziffernsummen von pi (Überlastung des Parameters, oder es wäre nur ein endlicher Unterschied, der auf diese Herausforderung angewendet wird), die präzise Übertragung von pi (Hinzufügen eines Indexes und Unterdrücken von Druckvorgängen) und die Pi-Fensterverschlüsselung .
Peter Taylor
3
@Suever natürlich! Diese Regel soll nur darauf hinweisen, dass 10k das Minimum ist, das Ihr Programm verarbeiten kann
Bassdrop Cumberwubwubwub
4
Ich empfehle, f (599) zu den Testfällen hinzuzufügen, da es leicht sein kann, sie falsch zu verstehen (Sie benötigen etwa 3 Dezimalstellen mehr Präzision).
Aditsu
2
Auch f (760) = 4, was die Folge 4 999999 8 beginnt , ist leicht falsch zu runden.
Anders Kaseorg

Antworten:

22

05AB1E, 3 Bytes

žs¤

Erklärt

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

Probieren Sie es online aus

Verwendet 1-basierte Indizierung.
Unterstützt bis zu 100.000 Stellen.

Emigna
quelle
Pi zu n Stellen rundet nicht?
Busukxuan
7
@busukxuan Nein. Es wurde eine vordefinierte Konstante von pi bis 100k Ziffern verwendet und N davon abgerufen.
Emigna
4
@Emigna Das ist sehr praktisch. Gute Lösung.
Suever
2
Kurz und scharf, PCG von seiner besten Seite
Xylius
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]

Die Eingabe erfolgt aus stdin.


Beispielnutzung

$ 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
quelle
Seien Sie vorsichtig bei der Verwendung von n im Algorithmus ... Die Ausgabe für 599 sollte 2 und nicht 1 sein. Außerdem möchten Sie möglicherweise angeben, dass Sie Python 2 verwenden.
aditsu
@aditsu aktualisiert. Bestätigt für alle n ≤ 1000 .
Primo
1
Wenn Sie nals Eingabe plus 9 annehmen , können Sie Parens vermeiden.
Xnor
@xnor d'oh. Danke;)
Primo
2
Die ersten Stellen, die von diesem Algorithmus generiert werden, sind '3.141596535897932…', wobei zwischen den Stellen 5 und 6 eine '2' fehlt. Warum? Denn dann fängt der `` Operator von Python 2 an, Lan den String anzuhängen.
Anders Kaseorg
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

Verbessert von Dennis . Vielen Dank!

Der Index ist einseitig.

Marco
quelle
11

Python 2, 73 71 73 Bytes

danke an @aditsu für die Erhöhung meiner Punktzahl um 2 Bytes

Endlich ein Algorithmus, der in weniger als 2 Sekunden abgeschlossen werden kann.

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 es!

Verwendet die Formel pi = 4*arctan(1)beim Berechnen arctan(1)mit der Taylor-Reihe.

Undichte Nonne
quelle
Ziemlich schnell. 1-Indizierung ist jedoch nicht in Python integriert. Das letzte Mal, dass ich mich erinnere (zugegebenermaßen war ich eine Weile inaktiv), war man sich einig, dass Funktionen definiert werden müssen, z f=lambda n:....
Primo
2
Fast jedes Lambda hier ist anonym (Sie können Antworten in Python auf dieser Site suchen)
Leaky Nun
Relevanter Metapost . Scheint in Verletzung der Regel 1 und 3 zu sein (nach dem Code ausgeführt wird , gibt es keine Möglichkeit , die Funktionsreferenz zu erfassen, die Funktionsdefinition für jeden Eingang werden müßte getippt ( (lambda n:`p`[n+1])(1), (lambda n:`p`[n+1])(2), ...).
primo
1
Sie können den Code nicht direkt ausführen. Es ist vergleichbar damit, importAnweisungen vorher zu platzieren , nur dass dies vorher einige globale Variablen erzeugt.
Undichte Nonne
i=3 while a:a=i/2*a/i;p+=a;i+=2für 4.
primo
7

MATL, 11 10 Bytes

1 Byte gespart dank @Luis

YPiEY$GH+)

Diese Lösung verwendet eine 1-basierte Indizierung

Probieren Sie es online

Alle Testfälle

Erläuterung

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
quelle
@ LuisMendo Oh ja, ich denke, die Ausgabe ist bereits ein String. Doh!
Suever
@ LuisMendo Oh, daran habe ich eigentlich nie gedacht. Ich benutze immer YPbeim Testen der symbolischen Toolbox
Suever
Ist YP überhaupt erlaubt? Die Frage sagt, es ist erlaubt, wenn es <= 10k Ziffern unterstützt
Busukxuan
@Suever OP hat "bis zu" und nicht "mindestens" angegeben. Meines Erachtens bedeutet dies, dass die Unterstützung von> 10k verboten ist.
Busukxuan
@Suever Yeah, ich denke, ich kann, obwohl ich nicht widerstehen kann, es zu tun, lol. Ich habe meine Sage-Antwort nur deswegen gelöscht.
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

DavidC
quelle
5

Salbei, 32 25 Bytes

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

Meine erste Antwort in einer solchen Sprache.

nrundet piauf 17775 Stellen.

busukxuan
quelle
1
Sie brauchen den printAufruf, sonst ist dies ein Ausschnitt, der nur in der REPL funktioniert.
Mego
Dies funktioniert (theoretisch) für alle Eingaben:lambda d:`n(pi,digits=d+5)`[-4]
Mego
2
@Mego gibt es nicht "99999" läuft?
Busukxuan
1
@Mego wird dann aber noch länger "9" laufen. Ich bin mir nicht sicher , ob die Länge verdoppeln kann es universal machen, aber ich glaube nicht einmal , dass es tun kann, aufgrund des Unendlichen Affe Satz: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan
1
@busukxuan Wenn Sie die nicht berechneten Stellen von π als zufällig modellieren, erwarten Sie sicherlich beliebig lange Läufe von 9s (und wir haben keinen Grund zu erwarten, dass das reale π anders ist, obwohl wir dies nicht bewiesen haben), aber Sie erwarten nur a Lauf von 9s, solange seine Position mit verschwindend geringer Wahrscheinlichkeit ist (obwohl wir erneut nicht bewiesen haben, dass sich das reale π nicht unerwartet verhält). Wir haben Läufe von mindestens neun Neunern gefunden, was meiner Meinung nach ausreicht, um den [-8]Vorschlag zu brechen .
Anders Kaseorg
4

CJam, 32

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

Online ausprobieren (etwas langsam)

aditsu
quelle
4

Mathematica, 23 21 Bytes

⌊10^# Pi⌋~Mod~10&

SageMath, 24 Bytes

lambda n:int(10^n*pi)%10
Anders Kaseorg
quelle
@LLlAMnYP Ich habe das versucht, aber Mathematica scheint ein Leerzeichen zwischen Piund (oder zwischen #und zu erfordern, wenn die Multiplikation gespiegelt ist), sodass die Speicherung verschwindet.
Anders Kaseorg
Eigentlich funktioniert es in Mathematica Online (ich hatte die Konsolenversion verwendet), also nehme ich es an, denke ich.
Anders Kaseorg
4
Dies sollten getrennte Antworten sein. Obwohl sie dieselbe Strategie anwenden, sind sie bei weitem nicht in der gleichen Sprache.
Mego
@Mego Die Richtlinie, die ich gefunden habe, besagt nicht, dass Antworten in verschiedenen Sprachen nicht als sehr ähnlich gelten können. (Die Antwort schlägt vor, dass dies nicht akzeptiert wurde.) Verweisen Sie auf eine andere Richtlinie oder nur auf eine Präferenz?
Anders Kaseorg
3

J , 19-15 Bytes

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

Nimmt eine ganze Zahl n und gibt die n- te Stelle von pi aus. Verwendet nullbasierte Indizierung. Um die n- te Ziffer zu erhalten, berechnen Sie pi mal 10 n + 1 , nehmen Sie das Floor dieses Werts und nehmen Sie dann modulo 10.

Verwendung

Die Eingabe ist eine erweiterte Ganzzahl.

   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

Auf meinem Rechner, dauert es etwa 18 Minuten , um die 10000 zu berechnen th Ziffer.

Erläuterung

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
Meilen
quelle
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)))

Wie Sie wahrscheinlich sehen können, habe ich keine Ahnung, was ich tue. Dies endete komischer als alles andere. Ich googelte "pi to n digits" und landete auf der Wikipedia-Seite für die Bailey-Borwein-Plouffe-Formel . Da ich kaum genug Kalkül (?) Kannte, um die Formel zu lesen, gelang es mir, sie in Clojure zu übersetzen.

Die Übersetzung selbst war nicht so schwierig. Die Schwierigkeit bestand in der Handhabung der Genauigkeit bis zu n Stellen, da die Formel dies erfordert (Math/pow 16 precision). das wird sehr schnell riesig. Ich musste BigDecimalüberall dafür verwenden, um zu arbeiten, was alles Dinge wirklich aufblähte.

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

Unnötig zu sagen, ich bin mir sicher, dass es einen einfacheren Weg gibt, dies zu tun, wenn Sie Mathe kennen.

(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])
Karzigenat
quelle
Mir wurde später klar, dass die Standardoperatoren tatsächlich mit großen Dezimalstellen arbeiten, sodass die Verknüpfungen oben nicht erforderlich sind. Ich montiere dies irgendwann zu beheben. Das wird wahrscheinlich ~ 50 Bytes kosten.
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)))

Berechnen Sie die Zahl pi mit dieser Formel . Makro muss neu definiert werden, with-precisionda es zu häufig verwendet wird.

Sie können die Ausgabe hier sehen: https://ideone.com/AzumC3 1000 und 10000 Takes überschreiten das Zeitlimit für Ideone, Achselzucken

Cliffroot
quelle
2

Python 3 , 338 Bytes

Diese Implementierung basiert auf dem Chudnovsky-Algorithmus , einem der schnellsten Algorithmen zur Schätzung von pi. Für jede Iteration werden ungefähr 14 Stellen geschätzt (siehe hier für weitere 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

Probieren Sie es online!

PieCot
quelle
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;}

Verwendet @ LeakyNuns Python 2-Algorithmus .

Ungolfed & Testcode:

Probieren Sie es hier aus.

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));
  }
}

Ausgabe:

1, 4, 1, 5, 8, 8, 2, 4, 3, 5
Kevin Cruijssen
quelle
1

Smalltalk - 270 Bytes

Verlässt sich auf die Identität tan⁻¹(x) = x − x³/3 + x⁵/5 − x⁷/7 ...und das π = 16⋅tan⁻¹(1/5) − 4⋅tan⁻¹(1/239). SmallTalk verwendet Integer-Arithmetik mit unbegrenzter Genauigkeit, sodass es bei großen Eingaben funktioniert, wenn Sie warten möchten!

|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

Speichern unter pi.stund Ausführen wie in den folgenden Testfällen. Die Indizierung basiert auf eins.

$ 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

quelle
1

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

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

Probieren Sie es online!

π/2=k=0k!/(2k+1)!!

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

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

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]

Probieren Sie es online!

π/4=arctan(1/2)+arctan(1/3)

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
quelle
0

Ahorn, 24 Bytes

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

Testfälle:

> 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
quelle
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;}

Probieren Sie es online!

TheLethalCoder
quelle