def first_triangular_with_k_divisors(k, lo=2, hi=10**3, pt=None): ''' --------------------------------------------------------------------------- first_triangular_with_k_divisors --------------------------------------------------------------------------- Returns the first triangular number that has k divisors. Searches in the range [lo, hi) initially, if it fails to find a result, then it doubles the search range by 2 (i.e. lo <- hi, hi <- 2*hi) and searches there. You can optionally provide lo and hi to start the search, otherwise, these default to 2 and 10**3. Uses a PrimeTools object to compute divisors, which can optionally be provided. If not provided, will use PrimeTools(hi * (hi+1) / 2). ''' if pt is None: pt = PrimeTools(triangle(hi)) else: pt.extend(triangle(hi)) for i in range(lo, hi): tri = triangle(i) n_divisors = pt.n_divisors(tri) if n_divisors > k: return tri else: return first_triangular_with_k_divisors(k, lo=hi, hi=2 * hi, pt=pt)
def find_nth_prime(n, pt=None): if pt is None: # if no primetools object has been provided, then # begin by finding all primes below 100 m = 100 pt = PrimeTools(m) # keep extending prime list until we have n primes while len(pt.prime_list) < n: m = 2 * m pt.extend(m) return pt.prime_list[n - 1]
def sum_primes_below(n, pt=None): ''' --------------------------------------------------------------------------- sum_primes_below --------------------------------------------------------------------------- Sum primes below n, excluding n itself. I.e. it returns: sum([p : p prime, p < n]) You can optionally provide a pre-computed PrimeTools object (pt) whose sieve will be extended if necessary. ''' if pt is None: pt = PrimeTools(n) else: pt.extend(n) return sum([p for p in pt.prime_list if p < n])