import utils d = {} utils.initialize_primes_cache(10001) for i in range(1, 10000): d[i] = sum(utils.proper_divisors(i)) def amicable_pairs(): for i in range(1, 10000): for j in range(i + 1, 10000): if d[i] == j and d[j] == i: yield i + j print(sum(amicable_pairs()))
from collections import Counter from functools import reduce from operator import mul import utils high = 100000 utils.initialize_primes_cache(high) # explanation: nth triangle number = n*(n-1)/2 = (n^2 - n)/2 < n^2 # highest prime factor of that can be sqrt # so n is upper bound on highest prime factor of nth triangle number s = 0 for i in range(1, high): s += i pf = Counter(utils.prime_factorization(s)) # explanation: we don't need to know the actual divisors, just how many of them there are # itertools.combinations would let us enumerate the actual divisors num_divisors = reduce(mul, (exp + 1 for (prime, exp) in pf.items()), 1) print(s, num_divisors) if num_divisors > 500: break
import utils utils.initialize_primes_cache(10**7 + 1) print("Primes initialized", flush=True) min_n = 10**7 min_ratio = 10**7 # note that n can't be prime because phi(p) = p-1 if p is prime - # this would minimize n/phi(n) but not satisfy permutation condition # skip even numbers because if n even , n/phi(n) closer to 2 for n in range(3, 10**7 + 1, 2): phi = utils.phi(n) if n / phi < min_ratio and utils.check_permutation(n, phi): min_ratio = n / phi min_n = n print((min_n, min_ratio), flush=True) print(min_n)
import utils upper_bound = 200000 num_consec = 4 utils.initialize_primes_cache(upper_bound) factors = dict((i, set(utils.prime_factorization(i))) for i in range(4, upper_bound)) for i in range(4, upper_bound): if all(len(factors[i+j]) >= num_consec for j in range(num_consec)): print(i, factors[i]) break
import utils from collections import Counter from operator import mul from functools import reduce BOUND = 1000001 utils.initialize_primes_cache(BOUND) print("done with cache", flush=True) factors = {} for i in range(BOUND, 2, -1): (n, d) = (3 * i - 1, 7 * i) (low_n, low_d) = utils.lowest_terms(n, d) if low_d < BOUND: print(low_n, low_d) break