Pi'yi ilet…


11

İtibaren ardından Pi Monte Carlo tahmin edicisi bu meydan sabiti Pi için en kısa kod üretmektir. Burada kodunuz sonsuza dek ardışık pi rakamlarını vermelidir.

Bu kod golf, bu yüzden makul bir bilgisayarda ilk 10.000 rakamdan daha kısa sürede ilk 10.000 basamağın çıkması ve asla sonlandırılmaması dışında en kısa gönderim (bayt cinsinden) kazanır.

Pi veya trig işlevleri için yerleşik bir özellik kullanamazsınız.


Kod boyutundaki sabit sınır kaldırıldı.


1
Tweetable ile, kodun 140 karakterden az olması gerektiği anlamına mı geliyor?
Ypnypn

5
Sorun, karakter sınırlaması olmadan zor görünüyor.
BobTheAwesome

1
@BobTheAwesome Popüler talebe göre karakter sınırlaması kaldırıldı.

1
@ mbomb007 Ondalık noktanın yazdırılması gerektiği veya rakamların boşlukla ayrılmayacağı açık değildir. Zorluk sadece "ardışık pi rakamları çıktısıdır". Ondalık nokta bir rakam değildir. 3141...bu - art arda pi.
orlp

1
Yazdırılan sayının Pi olması en iyisi olurdu, bu nedenle örneğin rakamlar arasında boşluk olmamalıdır. Ondalık noktayı içermesi daha iyi olurdu.

Yanıtlar:


7

CJam - 48

3.1o{1YAZ2*:Z#*{_2$*2$2*)/@)\}h*]:+sX2*:X>X<o1}g

Bu, π değerini 2 * toplam (k! / (2k + 1) !!) olarak daha büyük bir hassasiyetle hesaplar ve her adımda kaldığı yerden bir demet rakam basar.

Şunları yapabilirsiniz çevrimiçi deneyin sadece 8 (dış döngü) tekrarlamalar yapar ve 512 basamak yazdırır değiştirilmiş bir versiyonunu veya kullanmak java yorumlayıcısı gerçek şeyi. Dizüstü bilgisayarımda yaklaşık 6 saniye içinde 16384 basamağa ulaşıyor.

Not: Bu program belleğe aç; daha iyi davranan ama biraz daha uzun bir versiyon:

3.1o{T2AZ2*:Z#*1{@2$+@2$*2$2*)/@)1$}g;;sX2*:X>X<o1}g

Açıklama:

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 bayt

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 dosyasının uygulanması .


Beni 5 dakika dövdü ..... :)
Maltysen

Bu harika. Ancak rakamların tek bir satırda olmasını umuyordum. Başka bir deyişle, çıktı Pi'ye benzeyecektir.

2
@Lembik Cevabımı değiştirdim - 7 bayt daha uzun, ama şimdi hepsi bir satırda.
orlp

5

GolfScript (81 karakter)

1:i:^3{3i):i*(.(*3*.@*.5*3$27i*12-*+@^*:^5*/.print^*2$5i*2-*--\10*i*2i*(*\10*.}do

Çevrimiçi demo (makul bir masaüstünden çok daha yavaştır ve sınırlı sayıda döngü oluşturmak için önemsiz kod değişiklikleri vardır).

Elbette, daha önceki bir yorumda bahsettiğim tıkaç algoritmasını kullandım, ancak memnuniyetime golf oynamak biraz zaman aldı. Gibbons'ın makalesinde sunulan algoritma (sözde kod)

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
}

Yukarıdaki GolfScript (sözde kod) ile eşdeğerdir

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
}

bazı karakterleri başlatma ve yığın yönetimine kaydeder.


4

Pyth - 87 85 bayt

Http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf dosyasının başka bir çevirisi . Python yapacaktım ama @ orlp beni dövdü, bu yüzden Pyth yaptım. Bir tweet'e sığacak kadar küçük.

=H3=d1=bd=Gd#K+**hb27b6~b1=H*HK=d*dKJ/+*-*27b12G*5H*5d=H*T-H-*Jd*-*5b2G=G***GTbtybpkJ

Yazdırma ayarından gelen yazdırma arabelleği nedeniyle aralıklı adımlarla da olsa stdout'a çıktı verir end="". Spesifikasyon "ardışık rakamlar" dediğinden şu an ondalık noktayı yazdırmıyorum. Puanımı öldüren görevler.

=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

Burada deneyin . (Not: Çevrimiçi yorumlayıcı yalnızca tamamlanmış sonuçlar verdiğinden, sonsuz döngü dışarıdadır, bu nedenle yalnızca kod boyutunu artıran ilk 100 yazdırılır. Sonsuz denemek için yerel yorumlayıcıyı indirin.)

Zamanlama

Google bulut bilişim mikro örneğimde, gnu zamanına göre: real: 0m2.062sbu yüzden yeterince hızlı.


3

Scala, 599 bayt

Aşağıdaki kod , Pi Rakamları için A Spigot Algoritmasının Ek 2'sindeki Pascal kodunun düz bir portudur . Açıkçası çok az golf yapıldı. Kod, 10 saniyenin altında 10.000 basamak oluşturur piSpigot(10000)ve sonsuz bellek varsa, çok sayıda basamak üretmek için parametrelenebilir, ancak sonsuz değildir. Bunun sorun kısıtlamalarını karşılayıp karşılamadığından emin değilim, lütfen geri bildirim sağlayın.

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
Ben basamak reklam sonsuz üretmek için gereksinimi bir parametre alır bir yerine bir akış algoritması kullanmak anlamına gelir düşünüyorum n. Bkz. Örn. Cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf
Peter Taylor

Sonsuz hafıza ve sonsuz zaman sonsuz sayıda basamak vermelidir.

1

Befunge-98 (PyFunge), 120 bayt

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<

Çevrimiçi deneyin!

Bu, zaman sınırı bakımından sınırdır. Dizüstü bilgisayarımda 10.000 basamak yaklaşık 11 saniye sürüyor, ancak eminim bundan daha hızlı yapabilen "makul" bir bilgisayar olmalı.

Ancak, TIO üzerinde deniyorsanız, algoritma sonsuza kadar devam edecek şekilde tasarlandığından, 60 saniyelik zaman sınırına ulaşana kadar hiçbir şey döndürmeyeceğini unutmayın. O zamana kadar 10.000'den fazla basamağa sahip olacaksınız.

Jeremy Gibbons spigot algoritmasını kullanıyorum, buradaki diğer cevapların çoğu ile aynı olduğunu düşünüyorum. Ancak, bunun yorumlayıcıya keyfi hassas bellek hücrelerine dayandığını ve bunun desteklediğinin farkında olduğum tek uygulamanın PyFunge olduğunu unutmayın .

açıklama

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.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.