I've written bounded spigot algorithms(Spigot Algorithm) for e and pi. I would like to understand if there is anything I can do to make this more efficient. I've done things already like move the carry over check to the very end, precompute values etc.
You run the functions and pass it the number of digits you want i.e. print(pispig(1000))`
The spigot algorithm for computing functions you can apply a Horner schema to is one of the coolest things I have ever learned.
def espig(n):
estr = '2.'
(multq, asum, carover) = (0, 0, 0)
prec = 10 ** n
(remainders, tsum) = ([], [])
b = [x for x in range(2, n + 1)]
init = [1 for x in range(2, n + 1)]
x10 = [prec * x for x in init]
while True:
for (x, y) in zip(reversed(b), x10):
asum = carover + y
remainders.insert(0, asum % x)
tsum.insert(0, asum)
multq = asum // x
carover = multq
estr += str(int(tsum[0] // 2))
x10 = [prec * x for x in list(reversed(remainders))]
(carover, asum) = (0, 0)
(remainders, tsum) = ([], [])
if len(estr) > n:
break
return estr
def pispig(n):
e = n
xfact = 10 ** e
n = int(round(3.4 * n))
prec = n // 3.4
(pilist, remainders, tsum) = ([], [], [])
(multq, asum, carover, counter) = (0, 0, 0, 0)
a = [x for x in range(n)]
b = [2 * x + 1 for x in range(n)]
init = [2 for x in range(1, n + 1)]
x10 = [xfact * x for x in init]
while True:
for (A, B, R) in zip(reversed(a), reversed(b), reversed(x10)):
asum = carover + R
remainders.insert(0, asum % B)
tsum.insert(0, asum)
multq = asum // B
carover = multq * A
pilist.append(tsum[0] // 10)
remainders[0] = tsum[0] % xfact
x10 = [10 * x for x in list(remainders)]
(carover, asum) = (0, 0)
(remainders, tsum) = ([], [])
if len(''.join([str(x) for x in pilist])) > prec:
break
for D in reversed(pilist):
counter = 0
if D >= xfact:
pilist[pilist.index(D) - 1] += 1
pilist[pilist.index(D)] = pilist[pilist.index(D)] % xfact
counter += 1
return str('3.' + ''.join(str(x) for x in pilist[1:]))