Python - 191 byte
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 phiên bản nhanh hơn - 206 byte
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]))
Đầu vào được lấy từ stdin. Đầu ra cho n = 5000 mất khoảng 14 giây với tập lệnh thứ hai (hoặc 60 giây với tập đầu tiên).
Sử dụng mẫu:
$ 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
Công thức được sử dụng là như sau:
Trong đó A n là Số luân phiên thứ n , có thể được định nghĩa chính thức là số hoán vị xen kẽ trên một tập hợp kích thước n (xem thêm: A000111 ). Ngoài ra, chuỗi có thể được định nghĩa là thành phần của Số tiếp tuyến và Số bí mật ( A 2n = S n , A 2n + 1 = T n ), nhiều hơn về sau.
Hệ số hiệu chỉnh nhỏ c n nhanh chóng hội tụ đến 1 khi n trở nên lớn và được đưa ra bởi:
Với n = 1 , số tiền này để đánh giá Sê-ri Leibniz . Xấp xỉ π như 10 ½ , số lượng các điều khoản cần thiết có thể được tính như sau:
mà hội tụ (làm tròn lên) đến 17 , mặc dù các giá trị nhỏ hơn của n yêu cầu nhiều hơn đáng kể.
Để tính toán A n, có một số thuật toán và thậm chí là một công thức rõ ràng, nhưng tất cả chúng đều là bậc hai theo n . Ban đầu tôi đã mã hóa việc triển khai Thuật toán của Seidel , nhưng nó trở nên quá chậm để không thực tế. Mỗi lần lặp lại yêu cầu một thuật ngữ bổ sung được lưu trữ và các thuật ngữ tăng cường độ rất nhanh (loại "sai" của O (n 2 ) ).
Kịch bản đầu tiên sử dụng triển khai thuật toán ban đầu được đưa ra bởi Knuth và Buckholtz :
Đặt T 1, k = 1 với mọi k = 1..n
Các giá trị tiếp theo của T được đưa ra bởi mối quan hệ lặp lại:
T n + 1, k = 1/2 [ (k - 1) T n, k - 1 + (k + 1) T n, k + 1 ]
A n sau đó được cho bởi T n, 1
(xem thêm: A185414 )
Mặc dù không được nêu rõ ràng, thuật toán này tính toán đồng thời cả Số tiếp tuyến và Số bí mật. Kịch bản thứ hai sử dụng một biến thể của thuật toán này bởi Brent và Zimmermann , tính toán T hoặc S , tùy thuộc vào tính chẵn lẻ của n . Sự cải thiện là bậc hai theo n / 2 , do đó cải thiện tốc độ ~ 4x.