Пример #1
0
def largest_factor(x):
    possible = find_primes_less_than(int(
        x**0.5))  # to save time we only need prime numbers less than the sqrt
    i = 0
    while not (x in possible):
        if x % possible[i] == 0:
            x = int(x / possible[i])
        else:
            i += 1
    return x
def smallest_multiple(
    x
):  # x is the largest number in a series of 1 to x that are factors of the multiple
    i = 1
    factors = []

    # Checks for powers of primes less than the multiple,
    # we use roots to check for powers of primes less than our max multiple
    while x**(1 / i) > 2:
        factors += find_primes_less_than(int(x**(1 / i)))
        i += 1

    multiple = 1
    for i in factors:
        multiple *= i

    return multiple
Пример #3
0
def num_factors(x):
    if x == 1:
        return 1

    primes = find_primes_less_than(int(
        x**0.5))  # No primes would be a factor above the sqrt
    prime_powers = [0] * len(primes)

    for prime_index in range(len(primes)):
        while x % (
                primes[prime_index]**(prime_powers[prime_index] + 1)
        ) == 0:  # This counts the number of distinct primes and their exponent
            prime_powers[prime_index] += 1

    factors = 1

    for prime in range(
            len(primes)
    ):  # Factors can be counted using these numbers, ex: 28 -> 1, 2, 4, 7, 14, 28, where 28 == 2^2 * 7^1
        factors *= prime_powers[
            prime] + 1  # We then take each exponent, add 1 to each and multiply them together. ex: (2 + 1) * (1 + 1) == 6

    return factors
# 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?

from primes import find_primes_less_than

limit = 1000000
primes = find_primes_less_than(limit)
circular_primes = set(
    prime for prime in primes[:4]
)  # putting in single digit primes, use set to eliminate duplicates


def is_circular_prime(p):
    circ = {
        p,
    }
    if p in circular_primes:
        return {}
    if any(
            digit in '024568' for digit in str(p)
    ):  # numbers that end in an even or 5 cannot be prime, except 2 and 5
        return {}
    for permutation in range(1, len(str(p))):
        if int(str(p)[permutation:] + str(p)[:permutation]
               ) not in primes:  # cycles through the given number
            return {}
        circ.add(int(str(p)[permutation:] + str(p)[:permutation]))
    return circ  # returns a set of the circular prime and all its permutations
# It turns out that the formula will produce 40 primes for the consecutive integer values 0 <= n <= 39.
# However, when n = 40, 40^2 + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 41^2 + 41 + 41 is clearly divisible by 41.
#
# The incredible formula n^2 - 79n + 1601 was discovered, which produces 80 primes for the consecutive values 0 <= n <= 79.
# The product of the coefficients, −79 and 1601, is −126479.
#
# Considering quadratics of the form:
# n^2 + an + b, where |a| < 1000 and |b| < 1000
#
# where |n| is the modulus/absolute value of n
# e.g. |11| == 1 and |-4| == 4
# Find the product of the coefficients, a and b,
# for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n=0.

from primes import find_primes_less_than
primes = find_primes_less_than(100000)


def count_quadratic_primes(a, b):
    if b not in primes:
        return 0  # b must be prime, otherwise at x == 0 f(x) is not prime in f(x) = x^2 + ax + b
    n = 0

    # counts the number of primes in a row
    while n**2 + n * a + b in primes:
        n += 1

    return n


longest = 0
Пример #6
0
# The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
#
# Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
#
# NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.

from primes import find_primes_less_than

primes = find_primes_less_than(1000000)  # picked an arbitrary large number, if needed we can make it larger


def is_truncatable_prime(p):
    if any(digit in '0468' for digit in str(p)[:-1]):  # if these numbers are in at any point it cant be
        return False
    if any(digit in '25' for digit in str(p)[1:-1]):  # 2 and 5 can only come at the beginning of the number
        return False
    for digit in range(1, len(str(p))):  # checks each truncation for primeness
        if int(str(p)[digit:]) not in primes or int(str(p)[:digit]) not in primes:
            return False
    return True


truncatable_primes = set()

for prime in primes[4:]:  # skip single digits
    if is_truncatable_prime(prime):
        truncatable_primes.add(prime)


print(sum(truncatable_primes))  # 748317
# The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
# Find the sum of all the primes below two million.

from primes import find_primes_less_than

less_than_2_mil = find_primes_less_than(2000000)

print(sum(less_than_2_mil))  # 142913828922
Пример #8
0
# It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a prime and twice a square.
#
# 9 = 7 + 2×12
# 15 = 7 + 2×22
# 21 = 3 + 2×32
# 25 = 7 + 2×32
# 27 = 19 + 2×22
# 33 = 31 + 2×12
#
# It turns out that the conjecture was false.
#
# What is the smallest odd composite that cannot be written as the sum of a prime and twice a square?

from primes import find_primes_less_than

limit = 10000

primes = find_primes_less_than(
    limit)  # we generate arbitrarily large lists, of number to iterate through
squares = [i**2 for i in range(1, limit)]

for odd in [i for i in range(9, limit, 2) if i not in primes]:
    for square in squares[:int((
            odd // 2)**0.5)]:  # comparing to negatives is wasteful
        if odd - (2 * square) in primes:
            break
    else:
        print(odd)  # 5777
        break
Пример #9
0
# 646 = 2 × 17 × 19.
#
# Find the first four consecutive integers to have four distinct prime factors each. What is the first of these numbers?

from primes import find_primes_less_than


def count_prime_factors(x):
    prime_factor_count = 0
    for prime in primes[:int(
            x**0.5
    )]:  # only need to check up to the sqrt, this is an approximation
        if x % prime == 0:
            prime_factor_count += 1
    return prime_factor_count


limit = 1000000  # arbitrary large number
primes = find_primes_less_than(int(limit**0.5))

for i in [
        non_prime for non_prime in range(647, limit) if non_prime not in primes
]:  # skip to past the givens

    for j in range(4):
        if count_prime_factors(i + j) != 4:
            break
    else:
        print(i)  # 134043
        break
    for prime in primes[greatest:]:
        consecutive_lst.append(prime)

        while sum(consecutive_lst) > p:
            # if our smallest value times our longest length is greater than p, we know the length of p must be shorter
            if consecutive_lst.popleft() >= p // greatest:
                # we no longer care what value is returned as long as it is less than greatest
                return 1

        # the first time our list sums to p, return, as this is the longest the sum could be
        if sum(consecutive_lst) == p:
            return len(consecutive_lst)

    return 1  # our consecutive sum is only p


max_val = 10**6
primes = find_primes_less_than(max_val)

longest = 0
longest_len = 1

# rough estimate that our solution is between 950000 and 1000000
for i in primes[bisect.bisect_left(primes, max_val // 100 * 95):]:
    p_sum = consecutive_prime_sum(i, longest_len)

    if p_sum > longest_len:
        longest_len, longest = p_sum, i

print(longest)  # 997651, p_sum == 543
# We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime.
#
# What is the largest n-digit pandigital prime that exists?

from pandigital import is_n_pandigital
from primes import find_primes_less_than

# no pandigital prime exists above 7654321 because any pandigital number's sum of digits would be a multiple of 3,
# meaning they are a multiple of 3
primes = find_primes_less_than(7654321)

# since we are looking for the largest, we should go in reverse order,
# and stop at the first truthy value
for p in primes[::-1]:
    if is_n_pandigital(p, len(str(p))):
        print(p)  # 7652413
        break
Пример #12
0
# The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways:
# (i) each of the three terms are prime, and,
# (ii) each of the 4-digit numbers are permutations of one another.
#
# There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property,
# but there is one other 4-digit increasing sequence.
#
# What 12-digit number do you form by concatenating the three terms in this sequence?

from primes import find_primes_less_than
import itertools


primes = find_primes_less_than(10000)[168:]  # primes[168] == 1009, the first 4 digit prime
solutions = set()

for prime in primes:
    # create a list of all permutations of a prime
    permutations = [pr for pr in primes if tuple(str(pr)) in itertools.permutations(str(prime))]

    if len(permutations) >= 3:

        for combo in itertools.combinations(permutations, 3):
            # we check each combo for the arithmetic conditions
            if combo[1] - combo[0] == combo[2] - combo[1]:
                solutions.add(combo)
                break

for solution in solutions:
    print(*solution, sep='')  # 296962999629, we ignore the given 148748178147
Пример #13
0
    return factors


def amicable_pair(val_1):
    val_2 = sum(proper_factors(val_1))
    if val_1 == sum(proper_factors(val_2)) and val_1 != val_2:
        return val_2
    else:
        return False


possible_pairs = list(range(4, 10000))

pairs = []

primes = find_primes_less_than(possible_pairs[-1])

for i in possible_pairs:
    if i in primes:
        possible_pairs.remove(i)  # primes can never be part of an amicable pair, the only proper divisor is 1

while possible_pairs:
    if amicable_pair(possible_pairs[0]):  # we remove checked numbers and numbers that we know have a pair

        pairs += [possible_pairs[0]]
        pairs += [amicable_pair(possible_pairs[0])]

        possible_pairs.remove(amicable_pair(possible_pairs[0]))

    possible_pairs.remove(possible_pairs[0])