正の整数nを出力すると、最初のnの合計の小数部の桁π N。
入力と出力の例:
1→1
2→14
3→6
4→13
5→24
50→211
→211500 →2305 5000→22852
πの数字を計算する組み込み関数たり、べき級数や連続分数を評価したりするは許可されていません。標準の抜け穴が適用されます。入力/出力は便利な形式(stdin、stdout、関数in / outputなど)にすることができます。
正の整数nを出力すると、最初のnの合計の小数部の桁π N。
入力と出力の例:
1→1
2→14
3→6
4→13
5→24
50→211
→211500 →2305 5000→22852
πの数字を計算する組み込み関数たり、べき級数や連続分数を評価したりするは許可されていません。標準の抜け穴が適用されます。入力/出力は便利な形式(stdin、stdout、関数in / outputなど)にすることができます。
回答:
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高速バージョン-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]))
入力は標準入力から取得されます。n = 5000の出力には、2番目のスクリプトで約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は1に急速に収束しますとして、nが大きくなり、次式で与えられます。
以下のためのn = 1、評価するには、この量ライプニッツシリーズ。πを10として近似 ½、必要な項数は次のように計算することができます。
に収束(切り上げ) 17にますが、nの値が小さいほどかなり多くの値が必要になります。
A nの計算には、いくつかのアルゴリズムと明示的な式さえありますが、それらはすべてnの 2次です。私はもともとSeidelの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)
明示的には述べられていませんが、このアルゴリズムはタンジェント数とセカント数の両方を同時に計算します。2番目のスクリプトは、nのパリティに応じてTまたはSを計算するBrentとZimmermannによるこのアルゴリズムのバリエーションを使用します。改善はn / 2で2次であるため、約4倍の速度改善です。
二次収束を伴うπの計算での回答と同様のアプローチを取りました。最後の行は、πのN乗を取り、数字を合計します。N = 5000テストには1分ほどかかります。
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]))
いくつかのテスト:
$ 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
改変されていないコード:
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]))
a=j
しp=j
てa=p=j
iircに進むことができます。多分。
s<>j^u+/*GHhyHy^TyQr*TQ0ZQT_y*QQQ
isaacgによるこの回答に基づいています。おそらくもっとゴルフができるでしょう。スロー。
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.