Trasmetti Pi ... precisamente


11

In seguito allo stimatore di Monte Carlo del Pi questa sfida è quella di produrre il codice più breve per il Pi costante. Tranne qui il tuo codice deve generare cifre consecutive di pi per sempre.

Questo è il golf del codice, quindi vince l'invio più breve (in byte) tranne per il fatto che deve emettere le prime 10.000 cifre in meno di 10 secondi su un PC ragionevole e non deve mai terminare.

Non è possibile utilizzare alcun built-in per le funzioni Pi o Trig.


Rimosso il limite rigido per la dimensione del codice.


1
Con tweet, vuoi dire che il codice deve contenere meno di 140 caratteri?
Ypnypn,

5
Il problema in sé sembra impegnativo senza la limitazione del personaggio.
BobTheAwesome

1
@BobTheAwesome Rimosso il limite di caratteri dalla richiesta popolare.

1
@ mbomb007 Non è affatto ovvio che il punto decimale deve essere stampato o che le cifre potrebbero non essere separate da spazi bianchi. La sfida è semplicemente "produrre cifre consecutive di pi". Il punto decimale non è una cifra. 3141...è che - cifre consecutive di pi.
orlp

1
Sarebbe meglio se il numero stampato fosse Pi, per esempio non c'era spazio tra le cifre. Sarebbe ancora meglio se includesse il punto decimale.

Risposte:


7

CJam - 48

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

Questo calcola π come somma 2 * (k! / (2k + 1) !!) con sempre maggiore precisione e ad ogni passo stampa un gruppo di cifre da dove era stato interrotto.

Puoi provare online una versione modificata che esegue solo 8 iterazioni (loop esterno) e stampa 512 cifre oppure utilizzare l' interprete java per la cosa reale. Sul mio laptop arriva a 16384 cifre in circa 6 secondi.

Nota: questo programma ha molta fame di memoria; una versione migliore ma leggermente più lunga è:

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

Spiegazione:

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 byte

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

Implementazione di http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf .



Questo è fantastico Speravo comunque che le cifre fossero tutte su una riga. In altre parole, l'output sarebbe simile a Pi.

2
@Lembik Ho cambiato la mia risposta - 7 byte in più, ma ora tutto su una riga.
orlp

5

GolfScript (81 caratteri)

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

Demo online (che è molto più lento di un desktop ragionevole e ha banali modifiche al codice per eseguire un ciclo finito un numero finito di volte).

Ovviamente ho usato l'algoritmo Spigot che ho citato in un commento precedente, ma mi ci è voluto un po 'per giocarci golf con mia grande soddisfazione. L'algoritmo presentato nel documento di Gibbons è (pseudocodice)

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
}

Il GolfScript sopra è equivalente a (pseudocodice)

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
}

che salva alcuni caratteri nell'inizializzazione e nella gestione dello stack.


4

Pyth - 87 85 byte

Un'altra traduzione di http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf . Avrei fatto Python ma @orlp mi ha battuto, quindi ho fatto Pyth. Abbastanza piccolo da stare in un tweet.

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

Fornisce output a stdout, anche se in passaggi intermittenti a causa del buffer di stampa che deriva dall'impostazione end=""in stampa. Al momento non stampo il punto decimale poiché la specifica dice "cifre consecutive". Sono i compiti che stanno uccidendo il mio punteggio.

=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

Provalo qui . (Nota: poiché l'interprete online fornisce solo risultati completi, il ciclo infinito è fuori, quindi stampa solo i primi 100 che aumentano la dimensione del codice. Per provare infinito, scarica l'interprete locale.)

sincronizzazione

Sul mio google cloud calcolare la microistanza, secondo il tempo di gnu che ci è voluto: real: 0m2.062squindi è ovviamente abbastanza veloce.


3

Scala, 599 byte

Il codice seguente è una porta diritta del codice Pascal dall'Appendice 2 di A Spigot Algorithm for the Digits of Pi . Chiaramente molto poco golf è stato ancora fatto. Il codice genera 10.000 cifre in meno di 10 secondi con piSpigot(10000)e se uno ha memoria infinita può essere parametrizzato per generare molte cifre, ma non infinito. Non sono sicuro che questo soddisfi i vincoli del problema, quindi ti preghiamo di fornire un feedback.

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
Penso che il requisito di produrre cifre all'infinito significhi che è necessario utilizzare un algoritmo di streaming anziché uno che accetta un parametro n. Vedi ad esempio cs.ox.ac.uk/people/jeremy.gibbons/publications/spigot.pdf
Peter Taylor

La memoria infinita e il tempo infinito dovrebbero dare un numero infinito di cifre.

1

Befunge-98 (PyFunge), 120 byte

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<

Provalo online!

Questo è limite in termini di limite di tempo. 10.000 cifre impiegano circa 11 secondi sul mio laptop, ma sono sicuro che ci deve essere un PC "ragionevole" che potrebbe farlo più velocemente di così.

Tuttavia, se lo stai provando su TIO, nota che non restituirà nulla fino a quando non raggiungerà il limite di 60 secondi, poiché l'algoritmo è progettato per continuare all'infinito. A quel punto avrai comunque più di 10.000 cifre.

Sto usando l'algoritmo spigot di Jeremy Gibbons, che penso sia lo stesso della maggior parte delle altre risposte qui. Tuttavia, si noti che questo si basa sull'interprete con celle di memoria di precisione arbitrarie e l'unica implementazione di cui sono a conoscenza che supporta PyFunge .

Spiegazione

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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.