Trouver la nième décimale de pi

33

30 défis sont déjà dédiés à la pi mais pas un seul ne vous demande de trouver la nième décimale, alors ...

Défi

Pour tout entier dans la gamme de 0 <= n <= 10000 affichage, la nième décimale de pi.

Règles

  • Les décimales sont chaque nombre après 3.
  • Votre programme peut être une fonction ou un programme complet
  • Vous devez sortir le résultat en base 10
  • Vous pouvez obtenir nn'importe quelle méthode d'entrée appropriée (stdin, input (), paramètres de fonction, ...), mais pas codé en dur
  • Vous pouvez utiliser l' indexation 1 si elle est native de la langue de votre choix
  • Vous n'avez pas à traiter avec une entrée invalide ( n == -1, n == 'a'ou n == 1.5)
  • Les options intégrées sont autorisées si elles prennent en charge au moins 10 000 décimales.
  • Le temps d'exécution n'a pas d'importance, car il s'agit du code le plus court et non du code le plus rapide
  • Ceci est , le code le plus court en octets gagne

Cas de 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

Pour référence, voici les 100 premiers chiffres de pi.

Bassdrop Cumberwubwubwub
la source
Built-ins? par exemplestr(pi())[n+2]
primo
6
Les cibles de dupe les plus proches de l’OMI sont Calculer la somme des chiffres tronqués, la puissance de pi (surcharge le paramètre ou une différence finie appliquée à ce défi), Transmettre pi avec précision (ajoute un index et supprime certaines impressions) et chiffrement de fenêtre Pi .
Peter Taylor
3
@Suever ofcourse! Cette règle est juste pour souligner que 10k est le minimum que votre programme devrait être capable de gérer
Bassdrop Cumberwubwubwub
4
Je suggère d'ajouter f (599) aux cas de test, car il peut être facile de se tromper (vous avez besoin d'environ 3 décimales de précision supplémentaire).
Aditsu
2
De plus, f (760) = 4, qui commence la séquence 4 999999 8, est facile à arrondir de manière incorrecte.
Anders Kaseorg

Réponses:

22

05AB1E, 3 octets

žs¤

A expliqué

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

Essayez-le en ligne

Utilise l'indexation basée sur 1.
Prend en charge jusqu'à 100 000 chiffres.

Emigna
la source
Pi à n chiffres ne tourne pas?
busukxuan
7
@busukxuan Non. Il utilisait une constante prédéfinie de pi à 100k chiffres et récupérait N d'entre eux.
Emigna
4
@ Emigna C'est très pratique. Bonne solution.
Suever
2
Short et Sharp, PCG à son meilleur
Xylius
16

Python 2, 66 octets

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

L'entrée est prise de stdin.


Exemple d'utilisation

$ 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
la source
Faites attention à ne pas utiliser n dans l'algorithme ... la sortie pour 599 doit être 2 et non 1. Vous pouvez également vouloir spécifier que vous utilisez python 2.
aditsu
@aditsu mis à jour. Confirmé pour tout n ≤ 1000 .
Primo
1
Si vous prenez ncomme entrée plus 9, vous pouvez éviter les parens.
xnor
@xnor d'oh. Merci;)
primo
2
Les premiers chiffres générés par cet algorithme sont «3.141596535897932…», il manque un «2» entre les positions 5 et 6. Pourquoi? C'est à ce moment que l'opérateur `` `de Python 2 commence à ajouter un a Là la chaîne.
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

Amélioré par Dennis . Merci!

L'index est à base unique.

Marco
la source
11

Python 2, 73 71 73 octets

merci à @aditsu d'avoir augmenté mon score de 2 octets

Enfin un algorithme qui peut se terminer en moins de 2 secondes.

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 ça!

Utilise la formule pi = 4*arctan(1)lors du calcul à l' arctan(1)aide de sa série taylor.

Fuite, nonne
la source
Assez rapide. 1-indexation n'est pas natif à python, cependant. Enfin, je me souviens (je suis certes inactif depuis un moment), le consensus était que les fonctions devaient être définies, par exemple f=lambda n:....
Primo
2
Presque tous les lambda ici sont anonymes (vous pouvez chercher des réponses en python sur ce site)
Leaky Nun
Meta post pertinent . Semble être en violation de l' article 1 et 3 (après l' exécution de votre code, il n'y a aucun moyen de saisir la référence de la fonction, la définition de la fonction devrait être tapé pour chaque entrée ( (lambda n:`p`[n+1])(1), (lambda n:`p`[n+1])(2)...).
Primo
1
Vous ne pouvez pas exécuter le code directement. Cela revient à placer des importinstructions à l’avance, mais cela crée au préalable des variables globales.
Leaky Nun
i=3 while a:a=i/2*a/i;p+=a;i+=2pour 4.
Primo
7

MATL, 11 à 10 octets

1 octet enregistré grâce à @Luis

YPiEY$GH+)

Cette solution utilise l'indexation 1

Essayez-le en ligne

Tous les cas de test

Explication

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
la source
@LuisMendo Oh oui, je suppose que la sortie est déjà une chaîne. Doh!
Suever
@ LuisMendo Oh, je n'ai jamais pensé à cela. Je l'utilise toujours YPdans mes tests de la boîte à outils symbolique
mercredi
Est-ce que YP est autorisé? La question dit que c'est permis si elle supporte <= 10k chiffres
busukxuan
@Suever OP a déclaré "jusqu'à" plutôt que "au moins". À ma connaissance, cela signifie que supporter> 10k est interdit.
busukxuan
@Suever Ouais, je pense que je peux l'être, mais je ne peux pas résister à le faire lol. J'ai supprimé ma réponse Sage juste à cause de cela.
busukxuan
6

Mathematica 30 octets

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
la source
5

Sage, 32 à 25 octets

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

Ma première réponse dans une langue de ce genre.

narrondit pià 17775 chiffres.

busukxuan
la source
1
Vous avez besoin de l’ printappel ou bien c’est un extrait qui ne fonctionne que dans le REPL.
Mego
Cela fonctionne pour (théoriquement) toute entrée:lambda d:`n(pi,digits=d+5)`[-4]
Mégo
2
@ Mego il n'y a pas "99999" fonctionne?
busukxuan
1
@ Mego mais alors il y aura encore plus "9" exécutions. Je ne suis pas sûr que doubler la longueur puisse le rendre universel, mais je ne pense même pas que cela puisse le faire, en raison du théorème du singe infini: en.wikipedia.org/wiki/Infinite_monkey_theorem
busukxuan le
1
@busukxuan Si vous modélisez les chiffres non calculés de π comme aléatoires, vous vous attendez certainement à des longueurs arbitraires de 9 s (et nous n'avons aucune raison de penser que le réel π sera différent, bien que nous n'ayons pas prouvé cela), course de 9 tant que sa position est avec une probabilité infime (bien que, encore une fois, nous n’avons pas prouvé que le réel π ne se comporte pas de manière inattendue). Nous avons trouvé des exécutions d'au moins neuf 9, ce qui, à mon avis, est suffisant pour casser la [-8]proposition.
Anders Kaseorg
4

CJam, 32

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

Essayez-le en ligne (c'est un peu lent)

Aditsu
la source
4

Mathematica, 23 21 octets

⌊10^# Pi⌋~Mod~10&

SageMath, 24 octets

lambda n:int(10^n*pi)%10
Anders Kaseorg
la source
@LLlAMnYP J'ai essayé cela, mais Mathematica semble exiger un espace entre Piet (ou entre #et si la multiplication est inversée), de sorte que la sauvegarde disparaît.
Anders Kaseorg
En fait, cela fonctionne dans Mathematica Online (j'avais déjà utilisé la version console), alors je vais le prendre, je suppose.
Anders Kaseorg
4
Celles-ci devraient être des réponses séparées. Bien qu'ils utilisent la même stratégie, ils sont loin d'être la même langue.
Mego
@Mego La politique que j'ai trouvée ne dit pas que les réponses dans différentes langues ne peuvent pas compter comme très similaires. (La réponse suggérant que cela n'a pas été accepté.) Faites-vous référence à une autre politique ou simplement à une préférence?
Anders Kaseorg
3

J , 19 15 octets

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

Prend un entier n et délivre en sortie la n ième chiffre de pi. Utilise l'indexation à base zéro. Pour obtenir le n ième chiffre Compute fois pi 10 n + 1 , prenez la parole de cette valeur, puis modulo 10.

Usage

L'entrée est un entier étendu.

   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

Sur ma machine, il faut environ 18 minutes pour calculer le 10000 ème chiffre.

Explication

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
milles
la source
3

Clojure, 312 octets

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

Donc, comme vous pouvez probablement le constater, je n'ai aucune idée de ce que je fais. Cela a fini par être plus comique que tout. Je Google'd « pi à n chiffres », et a fini sur la page de Wikipédia pour la Formule BBP . Sachant à peine assez de calcul (?) Pour lire la formule, j'ai réussi à la traduire en Clojure.

La traduction elle-même n'était pas si difficile. La difficulté provenait de la précision de traitement jusqu’à n chiffres, puisque la formule l’exige (Math/pow 16 precision); qui devient énorme très vite. Je devais utiliser BigDecimalpartout pour que cela fonctionne, ce qui est vraiment gonflé les choses.

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

Inutile de dire que je suis sûr qu'il existe un moyen plus facile de s'y prendre si vous connaissez les mathématiques.

(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
la source
J'ai réalisé plus tard que les opérateurs standard travaillaient en réalité sur de grands nombres décimaux, de sorte que les raccourcis en haut ne sont pas nécessaires. Je vais résoudre ce problème à un moment donné. Cela va probablement supprimer ~ 50 octets.
Carcigenicate
2

Clojure, 253 octets

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

Calculez le nombre pi en utilisant cette formule . Je dois redéfinir la macro with-precisioncar elle est utilisée trop souvent.

Vous pouvez voir la sortie ici: https://ideone.com/AzumC3 Les prises 1000 et 10000 dépassent la limite de temps utilisée par idéone, les haussements d'épaules

cliffroot
la source
2

Python 3 , 338 octets

Cette implémentation est basée sur l’ algorithme de Chudnovsky , l’un des algorithmes les plus rapides pour estimer pi. Pour chaque itération, environ 14 chiffres sont estimés (regardez ici pour plus de détails).

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

Essayez-le en ligne!

PieCot
la source
1

Java 7, 262 260 octets

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

Utilisé @ LeakyNun de l'algorithme Python 2 .

Non testé et code de test:

Essayez ici.

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

Sortie:

1, 4, 1, 5, 8, 8, 2, 4, 3, 5
Kevin Cruijssen
la source
1

Smalltalk - 270 octets

S'appuie sur l'identité tan⁻¹(x) = x − x³/3 + x⁵/5 − x⁷/7 ..., et ça π = 16⋅tan⁻¹(1/5) − 4⋅tan⁻¹(1/239). SmallTalk utilise une arithmétique en nombres entiers de précision illimitée, ce qui fonctionnera pour les grandes entrées, si vous êtes prêt à attendre!

|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

Enregistrez sous pi.stet exécutez-le dans les cas de test suivants. L'indexation est basée.

$ 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

la source
1

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

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

Essayez-le en ligne!

En utilisant π/2=Σk=0k!/(2k+1)!!(Même logique utilisée par la réponse Python de Leaky Nun, mais c'est grâce à la syntaxe de JS que cela raccourcit). L'entrée est transmise à la fonction en tant que BigInt. 2 octets peuvent être supprimés si l'indexation 1 est utilisée:

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

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

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]

Essayez-le en ligne!

En utilisant π/4=arctan(1/2)+arctan(1/3). L'entrée est transmise à la fonction en tant que BigInt. 2 octets peuvent être supprimés si l'indexation 1 est utilisée:

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
la source
0

Maple, 24 octets

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

Cas de test:

> 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
la source
0

C #, 252 250 octets

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

Essayez-le en ligne!

TheLethalCoder
la source