Pi

Classical Algorithm

func pi(callback) {
    var (q, r, t, k, n, l) = (1, 0, 1, 1, 3, 3)
    loop {
        if ((4*q + r - t) < n*t) {
            callback(n)
            static _dot = callback('.')
            var nr = 10*(r - n*t)
            n = ((10*(3*q + r)) // t - 10*n)
            q *= 10
            r = nr
        }
        else {
            var nr = ((2*q + r) * l)
            var nn = ((q*(7*k + 2) + r*l) // (t*l))
            q *= k
            t *= l
            l += 2
            k += 1
            n = nn
            r = nr
        }
    }
}

STDOUT.autoflush(true)
pi(func(digit){ print digit })

Quicker, Unverified Algorithm

From the same .pdf mentioned throughout this task, from the last page. The original algorithm was written in Haskell, this is a translation which has also been optimized to avoid redundant multiplications. Same output, but the algorithm is based on one of Gosper’s series that yields more than one digit per term on average, so no test is made partway through the iteration. This is capable of producing approximately 100,000 digits at tio.run in the maximum 60 seconds allowed.

func p(c) { var(q,r,t,g,j,h,k,a,b,y) = (1,180,60,60,54,10,10,15,3)
  loop { c(y=(q*(a+=27) +5*r)//5*t); static _ = c('.')
    r=10*(g+=j+=54)*(q*(b+=5) +r -y*t); q*=h+=k+=40; t*=g } }
p(func(d){print d})

Last updated