Esempio n. 1
0
def problem518():
    LIMIT = 10 ** 8

    ans = 0
    isprime = eulerlib.list_primality(LIMIT - 1)

    # Search all possible x's. We know that c = x * z * z - 1. With the requirement c < LIMIT, we have x * z * z <= LIMIT.
    # Because z > y > 0, we know z >= 2. So at the very least we require x * 4 <= LIMIT. This implies x <= floor(LIMIT/4).
    for x in range(1, LIMIT // 4 + 1):

        # Search all possible y's. Notice that when y increases, 'a' strictly increases.
        # So when some y generates an 'a' such that a >= LIMIT, no candidates are possible with higher values of y.
        for y in itertools.count(1):
            a = x * y * y - 1
            if a >= LIMIT:
                break
            if not isprime[a]:
                continue

            # Search all valid z's. We require z > y and gcd(y, z) = 1. Notice that when z increases, c strictly increases.
            # So when some z generates a c such that c >= LIMIT, no candidates are possible with higher values of z.
            for z in itertools.count(y + 1):
                if math.gcd(y, z) != 1:
                    continue
                c = x * z * z - 1
                if c >= LIMIT:
                    break

                # Check whether (a, b, c) is a solution
                if isprime[c]:
                    b = x * y * z - 1
                    if isprime[b]:
                        ans += a + b + c

    return ans
Esempio n. 2
0
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
Esempio n. 3
0
def problem118():
    isprime = eulerlib.list_primality(10000)  # Cache for small numbers
    digits = list(range(1, 10))

    def count_prime_sets(startindex, prevnum):
        if startindex == len(digits):
            return 1
        else:
            result = 0
            for split in range(startindex + 1, len(digits) + 1):
                num = int("".join(map(str, digits[startindex:split])))
                if num > prevnum and is_prime(num):
                    result += count_prime_sets(split, num)
            return result

    def is_prime(n):
        if n < len(isprime):
            return isprime[n]
        else:
            return eulerlib.is_prime(n)

    ans = 0
    while True:
        ans += count_prime_sets(0, 0)
        if not eulerlib.next_permutation(digits):
            break
    return ans
Esempio n. 4
0
def problem329():
    START_NUM = 1
    END_NUM = 500
    CROAK_SEQ = "PPPPNNPPPNPPNPN"
    assert 0 <= START_NUM < END_NUM
    assert 1 <= len(CROAK_SEQ)

    NUM_JUMPS = len(CROAK_SEQ) - 1
    NUM_TRIALS = 2**NUM_JUMPS

    globalnumerator = 0
    isprime = eulerlib.list_primality(END_NUM)

    # For each starting square
    for i in range(START_NUM, END_NUM + 1):
        # For each sequence of jumps
        for j in range(NUM_TRIALS):

            # Set initial position and croak
            pos = i
            trialnumerator = 1
            if isprime[pos] == (CROAK_SEQ[0] == "P"):
                trialnumerator *= 2

            # Simulate each jump and croak
            for k in range(NUM_JUMPS):
                if pos <= START_NUM:
                    pos += 1  # Forced move
                elif pos >= END_NUM:
                    pos -= 1  # Forced move
                elif (j >> k) & 1 == 0:
                    pos += 1  # Chosen move
                else:
                    pos -= 1  # Chosen move

                # Multiply the running probability by 2/3 if primeness of current position
                # matches croak sequence at current index, otherwise multiply by 1/3
                if isprime[pos] == (CROAK_SEQ[k + 1] == "P"):
                    trialnumerator *= 2
            globalnumerator += trialnumerator

    # Calculate final probability fraction
    globaldenominator = (END_NUM + 1 -
                         START_NUM) * 2**NUM_JUMPS * 3**len(CROAK_SEQ)
    ans = fractions.Fraction(globalnumerator, globaldenominator)
    return ans
Esempio n. 5
0
def problem425():
    LIMIT = 10 ** 7

    isprime = eulerlib.list_primality(LIMIT)

    # pathmax[i] = None if i is not prime or i is not connected to 2.
    # Otherwise, considering all connection paths from 2 to i and for each path computing
    # the maximum number, pathmax[i] is the minimum number among all these maxima.
    pathmax = [None] * len(isprime)

    # Process paths in increasing order of maximum number
    queue = [(2, 2)]
    while len(queue) > 0:
        pmax, n = heapq.heappop(queue)
        if pathmax[n] is not None and pmax >= pathmax[n]:
            # This happens if at the time this update was queued, a better
            # or equally good update was queued ahead but not processed yet
            continue

        # Update the target node and explore neighbors
        pathmax[n] = pmax

        # Try all replacements of a single digit, including the leading zero.
        # This generates exactly all (no more, no less) the ways that a number m is connected to n.
        digits = to_digits(n)
        tempdigits = list(digits)
        for i in range(len(tempdigits)):  # For each digit position
            for j in range(10):  # For each digit value
                tempdigits[i] = j
                m = to_number(tempdigits)
                nextpmax = max(m, pmax)
                if (
                        m < len(isprime)
                        and isprime[m]
                        and (pathmax[m] is None or nextpmax < pathmax[m])
                ):
                    heapq.heappush(queue, (nextpmax, m))
            tempdigits[i] = digits[i]  # Restore the digit

    ans = sum(
        i
        for i in range(len(isprime))
        if isprime[i] and (pathmax[i] is None or pathmax[i] > i)
    )
    return ans
Esempio n. 6
0
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
Esempio n. 7
0
def count_circular_primes(upper_bound=999999):
    """
       The number, 197, is called a circular prime because all rotations of the
       digits: 197, 971, and 719, are themselves prime.

       There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37,
       71, 73, 79, and 97.

       How many circular primes are there below one million?
    """

    is_prime = eulerlib.list_primality(upper_bound)

    def is_circular_prime(input_n):
        n_string = str(input_n)
        return all(
            is_prime[int(n_string[i:] + n_string[:i])] for i in range(len(n_string))
        )

    ans = sum(1 for i in range(len(is_prime)) if is_circular_prime(i))
    return ans
Esempio n. 8
0
def problem357():
    """


    Consider the divisors of 30: 1,2,3,5,6,10,15,30.
       It can be seen that for every divisor d of 30, d+30/d is prime.

       Find the sum of all positive integers n not exceeding 100 000 000
       such thatfor every divisor d of n, d+n/d is prime.
    """
    limit = 10**8

    isprime = eulerlib.list_primality(limit + 1)

    def is_prime_generating(n):
        return all((n % d != 0 or isprime[d + n // d])
                   for d in range(2,
                                  eulerlib.sqrt(n) + 1))

    ans = sum(n for n in range(limit + 1)
              if isprime[n + 1] and is_prime_generating(n))
    return ans
Esempio n. 9
0
def problem051():
    """


    By replacing the 1^st digit of the 2-digit number *3, it turns out that
       six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all
       prime.

       By replacing the 3^rd and 4^th digits of 56**3 with the same digit, this
       5-digit number is the first example having seven primes among the ten
       generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663,
       56773, and 56993. Consequently 56003, being the first member of this
       family, is the smallest prime with this property.

       Find the smallest prime which, by replacing part of the number (not
       necessarily adjacent digits) with the same digit, is part of an eight
       prime value family.
    """
    isprime = eulerlib.list_primality(1000000)
    for i in range(len(isprime)):
        if not isprime[i]:
            continue

        n = [int(c) for c in str(i)]
        for mask in range(1 << len(n)):
            digits = do_mask(n, mask)
            count = 0
            for j in range(10):
                if digits[0] != 0 and isprime[to_number(digits)]:
                    count += 1
                digits = add_mask(digits, mask)

            if count == 8:
                digits = do_mask(n, mask)
                for j in range(10):
                    if digits[0] != 0 and isprime[to_number(digits)]:
                        return to_number(digits)
                    digits = add_mask(digits, mask)
    raise AssertionError("Not found")
Esempio n. 10
0
def problem500():
    TARGET = 500500
    MODULUS = 500500507
    isprime = eulerlib.list_primality(
        7376507)  # 500500th (1-based) prime number

    queue = []
    nextprime = 2
    heapq.heappush(queue, nextprime)

    ans = 1
    for _ in range(TARGET):
        item = heapq.heappop(queue)
        ans *= item
        ans %= MODULUS
        heapq.heappush(queue, item**2)

        if item == nextprime:
            nextprime += 1
            while not isprime[nextprime]:
                nextprime += 1
            heapq.heappush(queue, nextprime)

    return ans
Esempio n. 11
0
def count_consecutive_primes(a_b):
    """
    count_consecutive_primes for use a key=count_consecutive_primes
    :param a_b: tuple (a,b)
    :return: i
    """
    input_a, input_b = a_b
    i = 0
    for i in itertools.count():
        intermediate_n = i * i + i * input_a + input_b
        if not is_prime(intermediate_n):
            break
    return i


IS_PRIME_CACHE = eulerlib.list_primality(1000)


def is_prime(input_n):
    """
    cached version of eulerlib.is_prime
    :param input_n:
    :return:
    """
    if input_n < 0:
        return False
    if input_n < len(IS_PRIME_CACHE):
        return IS_PRIME_CACHE[input_n]
    return eulerlib.is_prime(input_n)

Esempio n. 12
0
def test_list_primality(input_n, expected_output):
    output = eulerlib.list_primality(input_n)
    print(output)
    assert output == expected_output