''' ============================================================ http://projecteuler.net/problem=118 Using all of the digits 1 through 9 and concatenating them freely to form decimal integers, different sets can be formed. Interestingly with the set {2,5,47,89,631}, all of the elements belonging to it are prime. How many distinct sets containing each of the digits one through nine exactly once contain only prime elements? ============================================================ ''' import itertools as it from math import log10, ceil from problem007 import primes from problem027 import is_prime P = primes('lt', int(98765432 ** 0.5) + 1) is_p = lambda x: is_prime(x, P) '''Digits = set of remaining digits. n_min = maximum number in set so far.''' # num_prime_sets = lambda digits, n_min: sum(num_prime_sets(digits - set(map(int, str(x))), x) for x in # it.ifilter(is_p, xrange(n_min + 1, min(100000000, int(''.join(sorted(map(str, digits), reverse=True))) + 1)))) if digits else 1 def num_prime_sets(digits, n_min, n_max=None): if not digits: return 1 digits_str = map(str, digits) eligible = (lambda x: x > n_min and x <= n_max and is_p(x)) if n_max else (lambda x: x > n_min and is_p(x)) max_digits = min(8, len(digits)) if n_max: max_digits = min(max_digits, int(ceil(log10(n_max)))) x_primes = it.ifilter(eligible, (int(''.join(x)) for r in xrange(1, max_digits + 1) for x in it.permutations(digits_str, r))) return sum(num_prime_sets(digits - set(map(int, str(x))), x) for x in x_primes) if __name__ == "__main__": print num_prime_sets(set(range(1, 10)), 0, 9876)
9 3 7 48073 For d = 0 to 9, the sum of all S(4, d) is 273700. Find the sum of all S(10, d). ============================================================ ''' import itertools as it, numpy as np from problem007 import primes from problem027 import is_prime def repeated_digit_nums(n, d, m): D = str(d) for stars in it.combinations(xrange(n), m): a = np.array(['*'] * n) a[np.array(stars)] = D free = np.array(list(set(range(n)) - set(stars))) for values in it.product('0123456789', repeat=n - m): a[free] = values if a[0] != '0': yield int(''.join(a)) S = lambda n, d, m, primes: sum(filter(lambda x: is_prime(x, primes), repeated_digit_nums(n, d, m))) def sum_s(n): p = primes('lt', 10 ** (0.5 * n)) return sum(it.dropwhile(lambda x: x[1] == 0, ((m, S(n, d, m, p)) for m in xrange(n - 1, 0, -1))).next()[1] for d in xrange(10)) if __name__ == "__main__": print sum_s(4) print sum_s(10)
The smallest positive integer n for which the numbers n2+1, n2+3, n2+7, n2+9, n2+13, and n2+27 are consecutive primes is 10. The sum of all such integers n below one-million is 1242490. What is the sum of all such integers n below 150 million? ============================================================ ''' from problem007 import primes from problem027 import is_prime from random import choice '''Fermat probable primality test''' N_LIST = 10 ** 6 SQRT_N_LIST = int(N_LIST ** 0.5) P = primes('lt', SQRT_N_LIST + 1) is_probable_prime = lambda n, tries = 20: all(pow(int(choice(P)), n - 1, n) == 1 for _ in xrange(tries)) isp = lambda x, tries = 20: is_prime(x, P) if x <= N_LIST else is_probable_prime(x, tries=tries) def consecutive_n(N, offset, complement, mods_primes=50): '''Return n for which {n^2+x: x in offset} is prime and {n^2+x: x in complement} is not prime.''' # Tabulate permissible remainders n mod p for the first mods_primes primes p p_list = primes('first', mods_primes) nc = int(p_list[-1] ** 0.5) + 1 R = [[all((i2 + x) % p for x in offsets) for i2 in (i * i for i in xrange(p))] for p in p_list] # By the Chinese remainder theorem, n must be of the form 210q + [10|80|130|200] for s in [10, 80, 130, 200]: for n in xrange(s, N, 210): n2 = n * n # First check against remainder table; if passes, run the more expensive primality test if (n <= nc or all(R[i][n % p] for i, p in enumerate(p_list))) and \ all(isp(n2 + x) for x in offsets) and all(not isp(n2 + x) for x in complement): yield n