Esempio n. 1
0
def concatenates_to_prime(a, b):
    """Returns whether both ab and ba are prime

    >>> concatenates_to_prime(109, 673)
    True
    """
    return is_prime(join_digits((a, b))) and is_prime(join_digits((b, a)))
Esempio n. 2
0
def solve() -> int:
    n = 7
    answer = -1
    
    # test all odd composite numbers for property
    while answer == -1:
        n += 2
        
        # skip number if it is not composite
        if prime.is_prime(n):
            continue
        
        # check if the given number is a counterexample
        is_counterexample = True
        primes = prime.primes_up_to(n)
        for p in primes:
            # test property for each prime
            diff = n - p
            if diff % FACTOR == 0 and seqs.is_square(diff // FACTOR):
                is_counterexample = False
                break
        
        # if property doesn't hold for this n, set it as answer
        if is_counterexample:
            answer = n
            
    return answer
Esempio n. 3
0
def solve():
    largest_pandigital_prime = 0

    for n in range(1, 10):
        digits = set(range(1, n + 1))

        for c in permutations(digits):
            candidate = join_digits(c)

            if is_prime(candidate):
                largest_pandigital_prime = candidate

    return largest_pandigital_prime
Esempio n. 4
0
def solve() -> int:
    total = 0

    # search for strong RTH primes with each number of digits up to POWER - 1
    rth_num_sums = [(0, 0)]
    for _ in range(POWER - 1):
        # build new RTH numbers by adding digits to previous list
        new_rth_num_sums = []
        candidate_nums = []
        for base_num, base_sum in rth_num_sums:
            base_part = base_num * 10
            for digit in range(10):
                new_num = base_part + digit
                new_sum = base_sum + digit

                # avoid dividing by 0
                if new_sum == 0:
                    continue

                # keep track of all strong RTH numbers
                div, mod = divmod(new_num, new_sum)
                if mod == 0:
                    new_rth_num_sums.append((new_num, new_sum))
                    if prime.is_prime(div):
                        candidate_nums.append(new_num)

        # prepare RTH numbers and their digit sums for next iteration
        rth_num_sums = new_rth_num_sums

        # check for strong RTH primes formed from RTH number bases
        for base_num in candidate_nums:
            base_part = base_num * 10
            for digit in range(1, 10, 2):
                n = base_part + digit
                if prime.is_prime(n):
                    total += n

    return total
Esempio n. 5
0
def solve():
    masks = defaultdict(set)

    for prime in gen_primes():
        digits = str(prime)

        for masked_digit in set(digits):
            masked = digits.replace(masked_digit, "x")

            for replaced_digit in range(10):
                candidate = int(masked.replace("x", str(replaced_digit)))

                # Discard leading zeros
                if len(str(candidate)) != len(masked):
                    continue

                if is_prime(candidate):
                    masks[masked].add(candidate)

            if len(masks[masked]) >= TARGET:
                return min(masks[masked])
Esempio n. 6
0
def solve() -> int:
    # TODO: find (provably) better lower bound on prime addend size
    primes = prime.primes_up_to(max(1000, LIMIT // 10))
    num_primes = len(primes)
    
    # create matrix with primes along diagonal
    dyna_sums: List[List[int]] = [[] for _ in range(num_primes)]
    for i in range(num_primes):
        dyna_sums[i] = [0] * num_primes
        dyna_sums[i][i] = primes[i]
    
    # compute dynamic sums, up to LIMIT - 1
    for j in range(1, num_primes):
        for i in range(j - 1, -1, -1):
            dyna_sum = dyna_sums[i][j - 1] + dyna_sums[j][j]
            if dyna_sum >= LIMIT:
                break
            else:
                dyna_sums[i][j] = dyna_sum
    
    # search for prime sum of max consecutive terms
    max_consec = -1
    best_prime = -1
    for i in range(num_primes):
        for j in range(i, num_primes):
            # stop searching if no more sums < LIMIT in current row
            if dyna_sums[i][j] == 0:
                break
            
            # check if sum meets criteria and is better than best so far
            if prime.is_prime(dyna_sums[i][j]):
                consec = j - i + 1
                if consec > max_consec:
                    max_consec = consec
                    best_prime = dyna_sums[i][j]
    
    return best_prime
Esempio n. 7
0
def solve() -> int:
    side = 1
    value = 1
    diag_count = 0
    prime_count = 0
    prime_frac = 1.0
    while prime_frac > MIN_FRACTION:
        # each layer has side length 2 greater than previous
        side += 2

        # count primes along diagonals of spiral
        side_sub_1 = side - 1
        for _ in range(4):
            # each diagonal is (side - 1) greater than previous
            value += side_sub_1

            # increment number of diagonal values and primes as necessary
            diag_count += 1
            if prime.is_prime(value):
                prime_count += 1

            prime_frac = prime_count / diag_count

    return side
Esempio n. 8
0
from common.primes import is_prime

TARGET = 0.1

n = 1
step = 2
total_diagonals = 1
diagonal_primes = set()

while True:
    for i in range(4):
        n += step
        total_diagonals += 1

        if is_prime(n):
            diagonal_primes.add(n)

    step += 2

    width = step - 1
    prime_ratio = len(diagonal_primes) / total_diagonals

    if prime_ratio < 0.1:
        print(width)
        break
Esempio n. 9
0
import itertools
from common.primes import gen_primes, is_prime

LIMIT = 1_000_000

primes = list(itertools.takewhile(lambda p: p < LIMIT, gen_primes()))

longest = 0
result = 0

for start in range(0, len(primes)):
    prime_slice = primes[start:]
    total = 0

    for length, prime in enumerate(prime_slice, 1):
        total += prime

        if total >= LIMIT:
            break

        if length > longest and is_prime(total):
            longest = length
            result = total

print(result)
Esempio n. 10
0
def solve() -> int:
    families: Set[Sequence[int]] = set()
    
    # test 5-digit numbers
    for i in range(1, 5):
        for digit_i in range(10):
            for digit_one in range(10):
                count = 0
                family = []
                for digit_repl in range(10):
                    if count < FAMILY_SIZE - (10 - digit_repl):
                        break
                    
                    num = digit_one
                    for d in range(1, 5):
                        if d == i:
                            num += digit_i * 10**d
                        else:
                            num += digit_repl * 10**d
                    
                    if prime.is_prime(num):
                        count += 1
                        family.append(num)
                        
                        if count == FAMILY_SIZE:
                            families.add(tuple(sorted(family)))
    
    # test 6-digit numbers
    for i in range(1, 6):
        for j in range(1, 6):
            for digit_i in range(10):
                for digit_j in range(10):
                    for digit_one in range(10):
                        count = 0
                        family = []
                        for digit_repl in range(10):
                            if count < FAMILY_SIZE - (10 - digit_repl):
                                break
                            
                            num = digit_one
                            for d in range(1, 6):
                                if d == i:
                                    num += digit_i * 10**d
                                elif d == j:
                                    num += digit_j * 10**d
                                else:
                                    num += digit_repl * 10**d
                            
                            if prime.is_prime(num):
                                count += 1
                                family.append(num)
                                
                                if count == FAMILY_SIZE:
                                    families.add(tuple(sorted(family)))
    
    # find min prime that satisfies problem requirements
    min_primes = []
    for fam in families:
        min_prime = fam[0]
        digit_count = digs.count_digits(min_prime)
        for i in range(1, len(fam)):
            if digs.count_digits(fam[i]) != digit_count:
                break
            min_primes.append(min_prime)
    
    return min(min_primes)
Esempio n. 11
0
def solve() -> int:
    total = 0
    
    # search for truncatable primes until MAX_COUNT are found
    count = 0
    m = 5
    while count < MAX_COUNT:
        # search for candidate prime numbers m < n around multiples of 6
        m += 6
        n = m + 2
        
        # check if m itself is prime before testing truncations
        if prime.is_prime(m):
            # check if m is a right truncatable prime
            right_trunc_prime = True
            for truncation in digs.digit_truncations_right(m):
                if truncation == m:
                    continue

                if not prime.is_prime(truncation):
                    right_trunc_prime = False
                    break
            
            # if necessary, check if m is also a left truncatable prime
            if right_trunc_prime:
                left_trunc_prime = True
                for truncation in digs.digit_truncations_left(m):
                    if truncation == m:
                        continue

                    if not prime.is_prime(truncation):
                        left_trunc_prime = False
                        break
                
                # if m is both a left and right truncatable prime, add to total
                if left_trunc_prime:
                    count += 1
                    total += m
        
        # check if n itself is prime before testing truncations
        if prime.is_prime(n):
            # check if n is a right truncatable prime
            right_trunc_prime = True
            for truncation in digs.digit_truncations_right(n):
                if truncation == n:
                    continue

                if not prime.is_prime(truncation):
                    right_trunc_prime = False
                    break
            
            # if necessary, check if n is also a left truncatable prime
            if right_trunc_prime:
                left_trunc_prime = True
                for truncation in digs.digit_truncations_left(n):
                    if truncation == n:
                        continue

                    if not prime.is_prime(truncation):
                        left_trunc_prime = False
                        break
                
                # if n is both a left and right truncatable prime, add to total
                if left_trunc_prime:
                    count += 1
                    total += n
    
    return total
Esempio n. 12
0
 def test_is_prime(self) -> None:
     primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53}
     for n in range(2, 59):
         self.assertEqual(prime.is_prime(n), n in primes)
     self.assertFalse(prime.is_prime(993))
     self.assertFalse(prime.is_prime(995))
     self.assertTrue(prime.is_prime(997))
     self.assertFalse(prime.is_prime(999))
     self.assertFalse(prime.is_prime(10006719))
     self.assertTrue(prime.is_prime(10006721))
     self.assertFalse(prime.is_prime(10006723))
     self.assertFalse(prime.is_prime(2097151))
     self.assertTrue(prime.is_prime(2147483647))
     self.assertFalse(prime.is_prime(4294967295))
Esempio n. 13
0
def concats_prime(n: int, m: int) -> bool:
    """Determines if n and m can concatenate in either order to form primes."""
    return (prime.is_prime(digs.concat_numbers(n, m)) and
            prime.is_prime(digs.concat_numbers(m, n)))
Esempio n. 14
0
def formula_primes(a, b):
    """Returns a list of primes generated by the formula."""
    return list(takewhile(lambda n: is_prime(n), gen_formula(a, b)))
Esempio n. 15
0
def is_prime(n: int) -> bool:
    """Memoized wrapper for the is_prime function."""
    return prime.is_prime(n)
Esempio n. 16
0
    >>> is_twice_square(2 * (3 ** 2))
    True

    >>> is_twice_square(2 * (4 ** 2))
    True
    """
    return ((n / 2) ** 0.5).is_integer()


def is_prime_plus_twice_square(n):
    """Returns whetner n can be written as a prime plus two times a square
    """
    for prime in PRIMES:
        if prime >= i:
            break

        if is_twice_square(i - prime):
            return True

    return False


for i in range(3, limit, 2):
    if is_prime(i):
        continue

    if not is_prime_plus_twice_square(i):
        print(i)
        break