def problem407(): LIMIT = 10**7 smallestprimefactor = eulerlib.list_smallest_prime_factors(LIMIT) ans = 0 for i in range(1, LIMIT + 1): # Compute factorization as coprime prime powers. e.g. 360 = {2^3, 3^2, 5^1} factorization = [] j = i while j != 1: p = smallestprimefactor[j] q = 1 while True: j //= p q *= p if j % p != 0: break factorization.append(q) solns = [0] modulus = 1 for q in factorization: # Use Chinese remainder theorem; cache parts of it recip = eulerlib.reciprocal_mod(q % modulus, modulus) newmod = q * modulus solns = [((0 + (x) * recip * q) % newmod) for x in solns] + [((1 + (x - 1) * recip * q) % newmod) for x in solns] modulus = newmod ans += max(solns) return ans
def problem134(): """ Let p and q be the two primes. Let k be the smallest power of 10 that exceeds p. The number that we seek is n = mk + p, where n is divisible by q, and m is minimized. (For example, p = 19, q = 23, k = 100, m = 12, n = 1219.) Firstly, n = mk + p = 0 mod q. By rearrangement, m = -p k^-1 mod q. (k^-1 exists because q is coprime with 10.) Then of course the smallest m that satisfies the divisibility condition is the one such that 0 <= m < q. :return: """ ans = 0 primes = eulerlib.list_primes(2000000) for i in itertools.count(2): p = primes[i] q = primes[i + 1] if p > 1000000: break k = 1 while k < p: k *= 10 m = (q - p) * eulerlib.reciprocal_mod(k % q, q) % q ans += m * k + p return ans
def chinese_remainder_theorem(a, p, b, q): return (a + (b - a) * eulerlib.reciprocal_mod(p % q, q) * p) % (p * q)
def test_reciprocal_mod(input_x, input_m, expected_output): output = eulerlib.reciprocal_mod(input_x, input_m) print(output) assert output == expected_output
def s(p): return (p - 3) * eulerlib.reciprocal_mod(8 % p, p) % p