Piを送信...正確に


11

Piのモンテカルロ推定量に続いて、この課題は定数Piの最短コードを生成することです。ここを除き、コードはpiの連続した数字を永久に出力する必要があります。

これはコードゴルフであるため、妥当なPCで10秒未満で最初の10,000桁を出力する必要があり、終了しないことを除いて、最短の提出(バイト単位)が勝ちます。

Piまたはtrig関数に組み込み関数を使用することはできません。


コードサイズのハード制限を削除しました。


1
ツイート可能ということは、コードが140文字未満でなければならないということですか?
イプニプン

5
この問題自体は、キャラクターの制限なしでは難しいようです。
BobTheAwesome

1
@BobTheAwesome人気のある需要による文字制限を削除しました。

1
@ mbomb007小数点を印刷する必要があることや、数字が空白文字で区切られていないことはまったく明らかではありません。課題は、単に「piの連続した数字を出力する」ことです。小数点は数字ではありません。3141...それは-piの連続した数字です。
-orlp

1
出力される数字がPiである場合、桁間にスペースがないようにするのが最適です。小数点が含まれていればさらに良いでしょう。

回答:


7

CJam-48

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

8

Python、138バイト

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の実装。


5分で私を
倒した

これは素晴らしい。しかし、数字がすべて1行になることを望んでいました。つまり、出力はPiのようになります。

2
@Lembik私は答えを変更しました-7バイト長くなりましたが、今ではすべてが1行になりました。
orlp

5

GolfScript(81文字)

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
}

これにより、初期化とスタック管理でいくつかの文字が保存されます。


4

Pyth- 87 85バイト

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明らかに十分に高速です。


3

Scala、599バイト

以下のコードは、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)

5
無限に数字を生成するという要件は、パラメータを取るものではなく、ストリーミングアルゴリズムを使用する必要があることを意味すると思いますn。例えば、cs.ox.ac.uk / people / jeremy.gibbons / publications / spigot.pdfを
Peter Taylor

無限のメモリと無限の時間は、無限の桁数を与えるべきです。

1

Befunge-98(PyFunge)、120バイト

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.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.