Piのモンテカルロ推定量に続いて、この課題は定数Piの最短コードを生成することです。ここを除き、コードはpiの連続した数字を永久に出力する必要があります。
これはコードゴルフであるため、妥当なPCで10秒未満で最初の10,000桁を出力する必要があり、終了しないことを除いて、最短の提出(バイト単位)が勝ちます。
Piまたはtrig関数に組み込み関数を使用することはできません。
コードサイズのハード制限を削除しました。
3141...
それは-piの連続した数字です。
Piのモンテカルロ推定量に続いて、この課題は定数Piの最短コードを生成することです。ここを除き、コードはpiの連続した数字を永久に出力する必要があります。
これはコードゴルフであるため、妥当なPCで10秒未満で最初の10,000桁を出力する必要があり、終了しないことを除いて、最短の提出(バイト単位)が勝ちます。
Piまたはtrig関数に組み込み関数を使用することはできません。
コードサイズのハード制限を削除しました。
3141...
それは-piの連続した数字です。
回答:
3.1o{1YAZ2*:Z#*{_2$*2$2*)/@)\}h*]:+sX2*:X>X<o1}g
これは、πを2 * sum(k!/(2k + 1)!!)としてより高い精度で計算し、すべてのステップで、中断した位置から数字の束を出力します。
あなたはできるオンライン試すだけ8(外側のループ)の繰り返しを行い、512の数字を印刷し修正版を、または使用するJavaインタプリタを本物のために。私のラップトップでは、約6秒で16384桁になります。
注:このプログラムは非常にメモリを消費します。より良い動作ですが、少し長いバージョンは次のとおりです。
3.1o{T2AZ2*:Z#*1{@2$+@2$*2$2*)/@)1$}g;;sX2*:X>X<o1}g
説明:
3.1o print 3.1
{…1}g repeat indefinitely
1YA push 1, 2 and 10 (Y=2, A=10)
Z2*:Z push Z*2 (Z=3 initially) and store back in Z
#* calculate 2*10^Z (2 from the formula and 10^Z for precision)
this is the term for k=0, and the earlier 1 represents k
{…}h do-while
at each iteration, the stack contains: terms, k, last-term
_2$* copy the previous term and k and multiply them
2$2*)/ divide the previous number by 2*k+1
this is the current term of the series
@)\ increment k and move it before the current term
the current term now serves as the loop condition
so the loop terminates when the term becomes 0
* multiply k and the last term (0), to get rid of k
]:+s put all the terms in an array, add them and convert to string
we obtain an approximation of π*10^Z
X2*:X push X*2 (X=1 initially) and store back in X
>X<o print X digits starting from the X position
q,r,t,i=1,180,60,2
while 1:u,y=27*i*(i+1)+6,(q*(27*i-12)+5*r)//(5*t);print(y,end="");q,r,t,i=10*q*i*(2*i-1),10*u*(q*(5*i-2)+r-y*t),t*u,i+1
http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdfの実装。
1:i:^3{3i):i*(.(*3*.@*.5*3$27i*12-*+@^*:^5*/.print^*2$5i*2-*--\10*i*2i*(*\10*.}do
オンラインデモ(合理的なデスクトップよりもはるかに遅く、限られた回数だけループするための簡単なコード変更があります)。
もちろん、以前のコメントで言及したスピゴットアルゴリズムを使用しましたが、満足のいくゴルフをするには少し時間がかかりました。ギボンズの論文に示されているアルゴリズムは(擬似コード)
q = 1; r = 180; t = 60; i = 2
while (true) {
u = 3*(3*i+1)*(3*i+2)
y = (q*(27*i-12)+5*r) / (5*t)
print y
r += q*(5*i-2)-y*t
r *= 10*u
q *= 10*i*(2*i-1)
t *= u
i += 1
}
上記のGolfScriptは(擬似コード)と同等です
t = i = q = 1; r = 3
while (true) {
u = 3*(3*i+1)*(3*i+2)
i += 1
r *= u
t *= u
y = (q*(27*i-12)+5*r) / (5*t)
print y
r -= y*t - q*(5*i-2)
q *= 10*i*(2*i-1)
r *= 10
}
これにより、初期化とスタック管理でいくつかの文字が保存されます。
http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdfの別の翻訳。Pythonをやるつもりでしたが、@ orlpが私を打ち負かしたので、Pythをしました。ツイートに収まるほど小さい。
=H3=d1=bd=Gd#K+**hb27b6~b1=H*HK=d*dKJ/+*-*27b12G*5H*5d=H*T-H-*Jd*-*5b2G=G***GTbtybpkJ
end=""
印刷の設定に起因する印刷バッファーのため、断続的なステップではありますが、stdoutに出力を提供します。仕様には「連続した数字」と書かれているため、現在は小数点を出力しません。そのスコアは私のスコアを殺している。
=H3 Set H to 3
=d1 Set d to 1
=bd Set b to d which is 1
=Gd Set G to d which is 1
# Infinte Loop
K Set K to
+**hb27b6 27*b*(b+1)+6
~b1 b+=1
=H*HK H*=K
=d*dK d*=K
J Set J to
/ Integer division
+*-*27b12G*5H G*(27*b-12)+5*H
*5d 5*d
=H Set H to
*T-H-*Jd*-*5b2G 10*(H-(J*d -G*(5*b-2)))
=G Set G to
***GTbtyb G*10*b*(2*b-1)
pkJ Print J with the end as "", not a newline
ここで試してみてください。(注:オンラインインタプリタは完全な結果のみを出力するため、無限ループが終了するため、最初の100だけが出力され、コードサイズが増加します。無限に試すには、ローカルインタプリタをダウンロードします。
私のgoogleクラウドコンピューティングマイクロインスタンスでは、gnu時間によると、real: 0m2.062s
明らかに十分に高速です。
以下のコードは、Piの桁のスピゴットアルゴリズムの付録2からのPascalコードのストレートポートです。明らかに、ゴルフはほとんど行われていません。コードは、10秒未満で10,000桁piSpigot(10000)
を生成します。無限メモリがある場合は、パラメータ化して多くの桁を生成できますが、無限ではありません。これが問題の制約を満たしているかどうかはわかりませんので、フィードバックを提供してください。
def piSpigot(n: Int): Unit = {
val len=10*n/3
var nines=0
var predigit=0
val a=Array.fill(len)(2)
(1 to n).foreach {_=>
var q=0
(1 to n).reverse.foreach{i=>
var x=10*a(i)+q*i
a(i)=x%(2*i-1)
q=x/(2*i-1)
}
a(1)=q%10
q/=10
if (q==9) {
nines+=1
} else if (q==10) {
print(predigit+1)
1.to(nines).foreach(_=>print(0))
predigit=0
nines=0
} else {
print(predigit)
predigit=q
if (nines!=0) {
1.to(nines).foreach(_=>print(9))
nines=0
}
}
}
println(predigit)
}
piSpigot(10000)
n
。例えば、cs.ox.ac.uk / people / jeremy.gibbons / publications / spigot.pdfを
cf*10p'<20p11>00p1+:30p:::*+39**6+:30g39**c-00g*10gv
>:2*1-*00g*a*^
^:p02*g02p01*a*-*g02\+g01*g00-2*5g03,+*86:/*5g02+*5<
これは、制限時間の点で境界線です。私のラップトップでは10,000桁で約11秒かかりますが、それよりも速く処理できる「合理的な」PCが必要だと確信しています。
ただし、TIOで試してみる場合は、アルゴリズムが永久に継続するように設計されているため、60秒の制限時間に達するまで何も返されないことに注意してください。その時までに、あなたは10,000桁以上を持っているでしょう。
私はジェレミー・ギボンズのスピゴット・アルゴリズムを使用していますが、これは他のほとんどの回答と同じだと思います。ただし、これは、任意の精度のメモリセルを持つインタープリターに依存していることに注意してください。
説明
cf*10p Initialise r to 180.
'<20p Initialise t to 60.
11 Initialise i and q on the stack to 1.
> Start of the main loop.
00p Save the current value of q in memory.
1+:30p Increment i and save a copy in memory.
:::*+39**6+ Calculate u = 27*(i*i+i)+6.
: Make a duplicate, since we'll need two copies later.
30g39**c-00g*10gv Calculate y = (q*(27*i-12)+5*r)/(5*t).
/*5g02+*5<
,+*86: Convert y to a character so we can output it.
*a*-*g02\+g01*g00-2*5g03 Calculate r = 10*u*(q*(i*5-2)+r-y*t)
p01 Save the updated r.
*g02 Calculate t = t*u
p02 Save the updated t.
>:2*1-*00g*a* Calculate q = 10*q*i*(i*2-1).
^:
^ Return to the start of the main loop.