Python - 191 Bytes
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]))
~ 4x schnellere Version - 206 Bytes
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]))
Die Eingabe erfolgt aus stdin. Die Ausgabe für n = 5000 dauert mit dem zweiten Skript ca. 14 Sekunden (mit dem ersten Skript ca. 60 Sekunden).
Beispielnutzung:
$ 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
Die verwendete Formel lautet wie folgt:
wo A n ist die n - te Alternating Anzahl , die formal als die Anzahl der alternierenden Permutationen auf einem Satz von Größe definiert werden kann n (siehe auch: A000111 ). Alternativ kann die Sequenz als die Zusammensetzung der Tangentenzahlen und Sekantenzahlen ( A 2n = Sn , A 2n + 1 = Tn ) definiert werden, dazu später mehr.
Der kleine Korrekturfaktor c n konvergiert schnell gegen 1, wenn n groß wird, und ist gegeben durch:
Für n = 1 bedeutet dies die Auswertung der Leibniz-Reihe . Annähern π als 10 ½ , kann die Anzahl der Begriffe erforderlich wie folgt berechnet:
die konvergiert (aufgerundet) auf 17 , obwohl kleinere Werte von n wesentlich mehr erfordern.
Für die Berechnung von A n gibt es mehrere Algorithmen und sogar eine explizite Formel, aber alle von ihnen durch quadratische sind n . Ich habe ursprünglich eine Implementierung von Seidels Algorithmus codiert , aber es wird zu langsam, um praktisch zu sein. Für jede Iteration muss ein zusätzlicher Term gespeichert werden, und der Betrag der Terme nimmt sehr schnell zu (die "falsche" Art von O (n 2 ) ).
Das erste Skript verwendet eine Implementierung eines Algorithmus, der ursprünglich von Knuth und Buckholtz angegeben wurde :
Sei T 1, k = 1 für alle k = 1..n
Nachfolgende Werte von T sind durch die Wiederholungsbeziehung gegeben:
T n + 1, k = 1/2 [ (k - 1) T n, k - 1 + (k + 1) T n, k + 1 ]
A n ist dann gegeben durch T n, 1
(siehe auch: A185414 )
Obwohl nicht explizit angegeben, berechnet dieser Algorithmus gleichzeitig die Tangentenzahlen und die Sekantenzahlen. Das zweite Skript verwendet eine Variation dieses Algorithmus von Brent und Zimmermann , die je nach Parität von n entweder T oder S berechnet . Die Verbesserung ist quadratisch um n / 2 , daher die Verbesserung der Geschwindigkeit um das Vierfache.