파이썬-191 바이트
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]))
~ 4 배 빠른 버전-206 바이트
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]))
입력은 stdin에서 가져옵니다. n = 5000의 출력 은 두 번째 스크립트에서 약 14 초 (또는 첫 번째 스크립트에서 60 초)가 걸립니다.
샘플 사용법 :
$ 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
사용 된 공식은 다음과 같습니다.
여기서 A n 은 n 번째 대체 수 이며, 크기 n 세트의 교호 순열 수로 공식적으로 정의 할 수 있습니다 (또한 A000111 참조 ). 대안 적으로, 서열은 탄젠트 수 및 시컨트 수 ( A 2n = S n , A 2n + 1 = T n ) 의 조성으로 정의 될 수 있으며 , 이에 대해서는 추후에 더 설명한다.
작은 보정 계수 c n 은 n 이 커짐에 따라 1 로 빠르게 수렴합니다 .
들어 N = 1 의 평가에이 양의 라이프니츠 시리즈 . π 를 10 ½ 로 근사 하면 필요한 항의 수는 다음과 같이 계산할 수 있습니다.
n의 값이 작을수록 더 많은 값이 필요 하지만 17로 수렴 합니다.
A n 의 계산 에는 몇 가지 알고리즘과 명시 적 공식이 있지만 모두 n 으로 이차합니다 . 원래 Seidel 's Algorithm 의 구현을 코딩 했지만 실용하기에는 너무 느립니다. 각 반복마다 추가 항을 저장해야하며 항의 크기가 매우 빠르게 증가합니다 ( "잘못된"종류의 O (n 2 ) ).
첫 번째 스크립트는 원래 Knuth와 Buckholtz에서 제공 한 알고리즘의 구현을 사용합니다 .
모든 k = 1..n에 대해 T 1, k = 1 이라고합시다.
T의 후속 값은 반복 관계에 의해 제공됩니다.
T n + 1, k = 1/2 [ (k-1) T n, k-1 + (k + 1) T n, k + 1 ]
A n 은 T n, 1에 의해 주어진다
(또한 참조 : A185414 )
명시 적으로 언급되지는 않았지만이 알고리즘은 탄젠트 수와 시컨트 수를 동시에 계산합니다. 제 스크립트에 의해이 알고리즘의 변형 사용 브렌과 짐머만 하는 산출하거나, T 또는 S 의 패리티에 따라 N을 . 개선은 n / 2 만큼 2 차적 이므로, ~ 4x 속도 개선입니다.