def triangular_divisors(n): if n%2==0: af = factor(n/2) bf = factor(n+1) else: af = factor((n+1)/2) bf = factor(n) triangular_factors = af + bf ndivizors = 1 for p, e in triangular_factors: ndivizors *= (e+1) return ndivizors
def divisor_iter(n): factorization = factor(n) # factorization of the current divisor divisor_fact = [(p, 0) for p, e in factorization] def _next_divisor_fact(): """ count up from 2**0 * 3*0 * ... to the factorization""" for i in xrange(len(factorization)): dp, de = divisor_fact[i] if de < factorization[i][1]: divisor_fact[i] = (dp, de + 1) return divisor_fact else: #overflow divisor_fact[i] = (dp, 0) if i == len(factorization) - 1: return None def _compute_divisor(): mul = 1 for p, e in divisor_fact: mul *= p**e return mul while True: yield _compute_divisor() if not _next_divisor_fact(): return
def pb12(): """ What is the value of the first triangle number to have over five hundred divisors? """ for i in xrange(2, 10**9): td = triangular_divisors(i) if (td >= 500): print i, td, i*(i+1)/2, factor(i*(i+1)/2) break
def totient(n, cached_primes=None): t = 1 for p, e in factor(n, cached_primes): t *= p**(e - 1) * (p - 1) return t