
# chudPi.py
'''
  Uses the Chudnovsky algorithm
  https://en.wikipedia.org/wiki/Chudnovsky_algorithm
  https://handwiki.org/wiki/Chudnovsky_algorithm

  input:
     1000       0.010 secs; 71 steps
     10000      3.430 secs; 706
     50000    155.277 secs
'''

import decimal
from decimal import Decimal as D, getcontext
import time
from decTrig import *


def chudPi():
  decimal.getcontext().prec += 2  
          # extra digits for intermediate steps
  C = 426880 * D(10005).sqrt()
  M = D(1)
  X = D(1)
  L = D(13591409)
  S = L
  pi = None
  i = 1
  while True:
    M = M * ((1728*i*i*i)-(2592*i*i)+(1104*i)-120)/(i*i*i)
    L = 545140134 + L
    X = -262537412640768000*X  # to generate power term
    S += (M*L) / X
    piPrev = pi
    pi = C/S
    i += 1
    # if calculated pi is not changing, break
    if pi == piPrev:
      print("No. steps:", i-1)
      break
  decimal.getcontext().prec -= 2
  return +pi    # unary plus applies the new precision


d = int(input("No. dps? "))
decimal.getcontext().prec = d
startTime = time.time()
piEst = chudPi()
endTime = time.time() - startTime
printGrouped(piEst)
print(f"Elapsed time: {endTime:.3f} secs")
