Ejemplo n.º 1
0
'''
============================================================
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)
Ejemplo n.º 2
0
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)    
Ejemplo n.º 3
0
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