Calcul des chiffres tronqués des sommes de puissances de pi

12

Étant donné un nombre entier positif n, la somme des n premiers chiffres décimaux de la partie fractionnaire de π n .

Exemple d'entrées et sorties:

1 → 1
2 → 14
3 → 6
4 → 13
5 → 24
50 → 211
500 → 2305
5000 → 22852

Les fonctions intégrées calculant des chiffres de π ou évaluant des séries de puissance ou des fractions continues ne sont pas autorisées. Des échappatoires standard s'appliquent. L'entrée / sortie peut être dans un format pratique (stdin, stdout, fonction entrée / sortie, etc.).

Le code le plus court en octets gagne.

orlp
la source
D'autres fonctions trigonométriques qui pourraient être utilisées pour calculer pi, mais pas nécessairement directement, comme les logarithmes arctangents ou imaginaires, sont-elles également interdites? De plus, existe-t-il une limite supérieure à n après laquelle il peut échouer?
FryAmTheEggman
@FryAmTheEggman Si ces fonctions trigonométriques peuvent calculer des chiffres arbitraires de pi, alors oui, elles sont interdites. Votre programme devrait fonctionner en théorie pour tout n , mais il est pardonné si l'exécution ou la mémoire devient trop élevée.
orlp

Réponses:

4

Python - 191 octets

t=i=1L;k=n=input();f=2000*20**n;A=range(n+1)
for k in range(2,n):A=[(A[j-1]+A[j+1])*j>>1for j in range(n-k+1)];f*=k
while k:k=(1-~i*n%4)*f/A[1]/i**n;t+=k;i+=2
print sum(map(int,`t`[-n-4:-4]))

~ Version 4x plus rapide - 206 octets

t=i=1L;k=n=input();f=2000*20**n;A=[0,1]+[0]*n
for k in range(1,n):
 f*=k
 for j in range(-~n/2-k+1):A[j]=j*A[j-1]+A[j+1]*(j+2-n%2)
while k:k=(1-~i*n%4)*f/A[1]/i**n;t+=k;i+=2
print sum(map(int,`t`[-n-4:-4]))

L'entrée provient de stdin. La sortie pour n = 5000 prend environ 14 secondes avec le deuxième script (ou 60 secondes avec le premier).


Exemple d'utilisation:

$ echo 1 | python pi-trunc.py
1

$ echo 2 | python pi-trunc.py
14

$ echo 3 | python pi-trunc.py
6

$ echo 4 | python pi-trunc.py
13

$ echo 5 | python pi-trunc.py
24

$ echo 50 | python pi-trunc.py
211

$ echo 500 | python pi-trunc.py
2305

$ echo 5000 | python pi-trunc.py
22852

La formule utilisée est la suivante:

A n est le n ème numéro alternatif , qui peut être formellement défini comme le nombre de permutations alternées sur un ensemble de taille n (voir aussi: A000111 ). Alternativement, la séquence peut être définie comme la composition des nombres tangents et des nombres sécants ( A 2n = S n , A 2n + 1 = T n ), plus à ce sujet plus tard.

Le petit facteur de correction c n converge rapidement vers 1 lorsque n devient grand et est donné par:

Pour n = 1 , cela revient à évaluer la série Leibniz . Approximativement π à 10 ½ , le nombre de termes requis peut être calculé comme suit:

qui converge (arrondi vers le haut) à 17 , bien que des valeurs plus petites de n nécessitent beaucoup plus.

Pour le calcul de A n, il existe plusieurs algorithmes, et même une formule explicite, mais tous sont quadratiques par n . J'ai codé à l'origine une implémentation de l'algorithme de Seidel , mais elle s'avère trop lente pour être pratique. Chaque itération nécessite un terme supplémentaire pour être stocké, et les termes augmentent très rapidement en amplitude (le "mauvais" type d' O (n 2 ) ).

Le premier script utilise une implémentation d'un algorithme initialement donné par Knuth et Buckholtz :

Soit T 1, k = 1 pour tout k = 1..n

Les valeurs suivantes de T sont données par la relation de récurrence:

T n + 1, k = 1/2 [ (k - 1) T n, k-1 + (k + 1) T n, k + 1 ]

A n est alors donné par T n, 1

(voir aussi: A185414 )

Bien qu'il ne soit pas explicitement indiqué, cet algorithme calcule simultanément les nombres tangents et les nombres sécants. Le deuxième script utilise une variation de cet algorithme de Brent et Zimmermann , qui calcule T ou S , selon la parité de n . L'amélioration est quadratique de n / 2 , d'où l'amélioration de la vitesse ~ 4x.

primo
la source
1
Excellente explication des mathématiques derrière votre réponse.
Logic Knight
3

Python 2, 246 octets

J'ai adopté une approche similaire à ma réponse à Calculer π avec convergence quadratique . La dernière ligne prend la Nième puissance de pi et additionne les chiffres. Le test N = 5000 prend environ une minute.

from decimal import*
d=Decimal
N=input()
getcontext().prec=2*N
j=d(1)
h=d(2)
f=h*h
g=j/h
a=j
b=j/h.sqrt()
t=j/f
p=j
for i in bin(N)[2:]:e=a;a,b=(a+b)/h,(a*b).sqrt();c=e-a;t-=c*c*p;p+=p
k=a+b
l=k*k/f/t
print sum(map(int,`l**N`.split('.')[1][:N]))

Quelques tests:

$ echo 1 | python soln.py
1
$ echo 3 | python soln.py
6
$ echo 5 | python soln.py
24
$ echo 500 | python soln.py
2305
$ echo 5000 | python soln.py
22852

Le code non golfé:

from decimal import *
d = Decimal

N = input()
getcontext().prec = 2 * N

# constants:
one = d(1)
two = d(2)
four = two*two
half = one/two

# initialise:
a = one
b = one / two.sqrt()
t = one / four
p = one

for i in bin(N)[2:] :
    temp = a;
    a, b = (a+b)/two, (a*b).sqrt();
    pterm = temp-a;
    t -= pterm*pterm * p;
    p += p

ab = a+b
pi = ab*ab / four / t
print sum(map(int, `pi ** N`.split('.')[1][:N]))
Logic Knight
la source
Ligne 8, vous pouvez activer a=jet p=jà a=p=jIIRC. Peut être.
Elias Benevedes
Merci. Il y a plus d'optimisations de golf pour ce code, mais il ne sera pas compétitif sans une réécriture utilisant un algorithme sans Decimal.
Logic Knight
1

Pyth, 33

s<>j^u+/*GHhyHy^TyQr*TQ0ZQT_y*QQQ

Basé sur cette réponse de isaacg . Pourrait probablement être plus joué au golf. Lent.

s<>j            Digit sum of...
  ^                 
    u               Evaluate pi = 2 + 1/3*(2 + 2/5*(2 + 3/7*(2 + 4/9*(2 + ...))))
      +
        /
          *GH
          hyH
        y^TyQ       Except we generate a large integer containing 2n digits,
                    rather than a fraction.
      r*TQ0         Experimentally verified that 10*n iterations will give enough
                    precision for 2n digits (# digits correct grows faster than 2n).
      Z
    Q               To the nth power.
  T_y*QQQ         Get the last 2n^2 digits (all the fractional digits) and get the
                  first n fractional digits.
orlp
la source
1
Cette réponse a vraiment besoin d'explications au moins suffisantes pour justifier qu'elle calcule suffisamment de chiffres pour obtenir la bonne réponse.
Peter Taylor
@PeterTaylor J'ajouterai une explication demain, sur le point d'aller me coucher.
orlp
Chaque itération produit un bit correct (voir l' annexe A ). 2n chiffres devraient nécessiter ~ 6,64n itérations.
primo