def problem087(): """ The smallest number expressible as the sum of a prime square, prime cube, and prime fourth power is 28. In fact, there are exactly four numbers below fifty that can be expressed in such a way: 28 = 2^2 + 2^3 + 2^4 33 = 3^2 + 2^3 + 2^4 49 = 5^2 + 2^3 + 2^4 47 = 2^2 + 3^3 + 2^4 How many numbers below fifty million can be expressed as the sum of a prime square, prime cube, and prime fourth power? """ limit = 50000000 primes = eulerlib.list_primes(eulerlib.sqrt(limit)) sums = {0} for i in range(2, 5): newsums = set() for p in primes: q = p**i if q > limit: break for x in sums: if x + q <= limit: newsums.add(x + q) sums = newsums return len(sums)
def problem111(): DIGITS = 10 primes = eulerlib.list_primes(eulerlib.sqrt(10**DIGITS)) # Only valid if 1 < n <= 10^DIGITS. def is_prime(n): end = eulerlib.sqrt(n) for p in primes: if p > end: break if n % p == 0: return False return True ans = 0 # For each repeating digit for digit in range(10): # Search by the number of repetitions in decreasing order for rep in range(DIGITS, -1, -1): sum = 0 digits = [0] * DIGITS # Try all possibilities for filling the non-repeating digits for i in range(9**(DIGITS - rep)): # Build initial array. For example, if DIGITS=7, digit=5, rep=4, i=123, then the array will be filled with 5,5,5,5,1,4,7. for j in range(rep): digits[j] = digit temp = i for j in range(DIGITS - rep): d = temp % 9 if d >= digit: # Skip the repeating digit d += 1 if ( j > 0 and d > digits[DIGITS - j] ): # If this is true, then after sorting, the array will be in an already-tried configuration break digits[-1 - j] = d temp //= 9 else: digits.sort() # Start at lowest permutation while True: # Go through all permutations if ( digits[0] > 0 ): # Skip if the number has a leading zero, which means it has less than DIGIT digits num = int("".join(map(str, digits))) if is_prime(num): sum += num if not eulerlib.next_permutation(digits): break if sum > 0: # Primes found; skip all lesser repetitions ans += sum break return ans
def problem050(): """ The prime 41, can be written as the summation of six consecutive primes: 41 = 2 + 3 + 5 + 7 + 11 + 13 This is the longest summation of consecutive primes that adds to a prime below one-hundred. The longest summation of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953. Which prime, below one-million, can be written as the summation of the most consecutive primes? """ ans = 0 isprime = eulerlib.list_primality(999999) primes = eulerlib.list_primes(999999) consecutive = 0 for i in range(len(primes)): summation = primes[i] consec = 1 for j in range(i + 1, len(primes)): summation += primes[j] consec += 1 if summation >= len(isprime): break if isprime[summation] and consec > consecutive: ans = summation consecutive = consec return ans
def problem304(): BASE = 10 ** 14 SEARCH_RANGE = ( 10000000 ) # Number of candidates starting from BASE to search for primes. Hopefully there are 100 000 primes among here. MODULUS = 1234567891011 # iscomposite[i] pertains to the number BASE + i # Sieve of Eratosthenes, but starting at BASE iscomposite = [False] * SEARCH_RANGE primes = eulerlib.list_primes(eulerlib.sqrt(BASE + SEARCH_RANGE)) for p in primes: for i in range((BASE + p - 1) // p * p - BASE, len(iscomposite), p): iscomposite[i] = True # Returns p - BASE, where p is the next prime after n + BASE def next_prime(n): while True: n += 1 if n >= len(iscomposite): raise AssertionError("Search range exhausted") if not iscomposite[n]: return n ans = 0 p = 0 for i in range(100000): p = next_prime(p) ans = (ans + fibonacci_mod(BASE + p, MODULUS)) % MODULUS 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 problem146(): LIMIT = 150000000 INCREMENTS = [1, 3, 7, 9, 13, 27] # Must be in non-decreasing order NON_INCREMENTS = set(range(INCREMENTS[-1])) - set(INCREMENTS) maxnumber = LIMIT ** 2 + INCREMENTS[-1] primes = eulerlib.list_primes(eulerlib.sqrt(maxnumber)) def has_consecutive_primes(n): # Generate the set of numbers to test for primality n2 = n ** 2 temp = [(n2 + k) for k in INCREMENTS] # Test that each number is prime. # Note: The nesting of the loops can be reversed, but this way is much faster. if any((x != p and x % p == 0) for p in primes for x in temp): return False # Test that each number that is not an increment is composite. # This checks that the prime numbers we found are in fact consecutive. return all((not is_prime(n2 + k)) for k in NON_INCREMENTS) def is_prime(n): end = eulerlib.sqrt(n) for p in primes: if p > end: break if n % p == 0: return False return True ans = sum(n for n in range(0, LIMIT, 10) if has_consecutive_primes(n)) return ans
def problem010(): """ The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. Find the sum of all the primes below two million. Call the sieve of Eratosthenes and sum the primes found. """ ans = sum(eulerlib.list_primes(1999999)) return ans
def problem187(): LIMIT = 10**8 - 1 ans = 0 primes = eulerlib.list_primes(LIMIT // 2) sqrt = eulerlib.sqrt(LIMIT) for (i, p) in enumerate(primes): if p > sqrt: break end = binary_search(primes, LIMIT // p) ans += (end + 1 if end >= 0 else -end - 1) - i return ans
def problem204(): LIMIT = 10**9 primes = eulerlib.list_primes(100) def count(primeindex, product): if primeindex == len(primes): return 1 if product <= LIMIT else 0 else: result = 0 while product <= LIMIT: result += count(primeindex + 1, product) product *= primes[primeindex] return result return count(0, 1)
def problem347(): """ The largest integer ≤ 100 that is only divisible by both the primes 2 and 3 is 96, as 96=32*3=2^5*3.For two distinct primes p and q let M(p,q,N) be the largest positive integer ≤N only divisibleby both p and q and M(p,q,N)=0 if such a positive integer does not exist. E.g. M(2,3,100)=96. M(3,5,100)=75 and not 90 because 90 is divisible by 2 ,3 and 5. Also M(2,73,100)=0 because there does not exist a positive integer ≤ 100 that is divisible by both 2 and 73. Let S(N) be the sum of all distinct M(p,q,N).S(100)=2262. Find S(10 000 000). """ limit = 10000000 possible = set() primes = eulerlib.list_primes(limit // 2) end = eulerlib.sqrt(limit) for i in range(len(primes)): p = primes[i] if p > end: break for j in range(i + 1, len(primes)): q = primes[j] lcm = p * q if lcm > limit: break multlimit = limit // lcm multiplier = 1 while multiplier * p <= multlimit: multiplier *= p maxmult = multiplier while multiplier % p == 0: multiplier //= p while multiplier * q <= multlimit: multiplier *= q maxmult = max(multiplier, maxmult) possible.add(maxmult * lcm) ans = sum(possible) return ans
def problem249(): LIMIT = 5000 MODULUS = 10**16 # Use dynamic programming. count[i] is the number of subsets of primes with the sum of i, modulo MODULUS. count = [0] * (LIMIT**2 // 2) count[0] = 1 s = ( 0 ) # Sum of all primes seen so far, and thus the highest index among nonzero entries in 'count' for p in eulerlib.list_primes(LIMIT): for i in reversed(range(s + 1)): count[i + p] = (count[i + p] + count[i]) % MODULUS s += p isprime = eulerlib.list_primality(s + 1) ans = sum(count[i] for i in range(s + 1) if isprime[i]) % MODULUS return ans
def problem203(): # Collect unique numbers in Pascal's triangle numbers = set(eulerlib.binomial(n, k) for n in range(51) for k in range(n + 1)) maximum = max(numbers) # Prepare list of squared primes primes = eulerlib.list_primes(eulerlib.sqrt(maximum)) primessquared = [p * p for p in primes] def is_squarefree(n): for p2 in primessquared: if p2 > n: break if n % p2 == 0: return False return True # Sum up the squarefree numbers ans = sum(n for n in numbers if is_squarefree(n)) return ans
def problem133(): primes = eulerlib.list_primes(100000) ans = sum(p for p in primes if p == 2 or p == 5 or not has_divisible_repunit(p)) return ans
def problem123(): primes = eulerlib.list_primes(1000000) for n in range(5, len(primes), 2): rem = n * primes[n - 1] * 2 if rem > 10000000000: return n
def test_list_primes(input_n, expected_output): output = eulerlib.list_primes(input_n) print(output) assert output == expected_output
def problem060(): """ The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property. Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime. """ prime_limit = 100000 # Arbitrary initial cutoff primes = eulerlib.list_primes(prime_limit) # Tries to find any suitable set and return its sum, or None if none is found. # A set is suitable if it contains only primes, its size is targetsize, # its sum is less than or equal to sumlimit, and each pair concatenates to a prime. # 'prefix' is an array of ascending indices into the 'primes' array, # which describes the set found so far. # The function blindly assumes that each pair of primes in 'prefix' concatenates to a prime. # For example, find_set_sum([1, 3, 28], 5, 10000) means "find the sum of any set # where the set has size 5, consists of primes with the lowest elements being [3, 7, 109], # has sum 10000 or less, and has each pair concatenating to form a prime". def find_set_sum(prefix, targetsize, sum_limitation): if len(prefix) == targetsize: return sum(primes[i] for i in prefix) else: istart = 0 if (len(prefix) == 0) else (prefix[-1] + 1) for i in range(istart, len(primes)): if primes[i] > sum_limitation: break if all((is_concat_prime(i, j) and is_concat_prime(j, i)) for j in prefix): prefix.append(i) result = find_set_sum(prefix, targetsize, sum_limitation - primes[i]) prefix.pop() if result is not None: return result return None # Tests whether concat(primes[x], primes[y]) is a prime number, with memoization. @eulerlib.Memoize def is_concat_prime(x, y): return is_prime(int(str(primes[x]) + str(primes[y]))) # Tests whether the given integer is prime. The implementation performs trial division, # first using the list of primes named 'primes', then switching to simple incrementation. # This requires the last number in 'primes' (if any) to be an odd number. def is_prime(x): if x < 0: raise ValueError() elif x in (0, 1): return False else: end = eulerlib.sqrt(x) for p in primes: if p > end: break if x % p == 0: return False for i in range(primes[-1] + 2, end + 1, 2): if x % i == 0: return False return True sumlimit = prime_limit while True: setsum = find_set_sum([], 5, sumlimit - 1) if setsum is None: # No smaller sum found return sumlimit sumlimit = setsum