def is_goldbach_number(n: int) -> bool: '''only works on odd composite numbers''' assert isinstance(n, int) and n > 0 assert n % 2 == 1 and not is_prime(n) # first call operations if _goldbach.__last_prime == 0: next(_goldbach.__prime_gen) # skip 2 _goldbach.__last_prime = 2 # check if n was already found if n in _goldbach.__known: return True # make sure all primes less than n add in stack while _goldbach.__last_prime + 2 < n: prime = next(_goldbach.__prime_gen) square = 1 total = prime + 2 _goldbach.__last_prime = prime _goldbach.__stack.append((prime, square, total)) _goldbach.__known.add(total) if total == n: return True # go through each prime on stack and increment totals until greater # than n or n is found for index, (prime, square, total) in enumerate(_goldbach.__stack): while total < n: square += 1 total = prime + 2 * square * square _goldbach.__known.add(total) _goldbach.__stack[index] = (prime, square, total) if total == n: return True return False
def is_trunc_right_to_left(number: int) -> bool: '''checks if a number is truncatable right to left while remaining prime''' while number > 0: if not is_prime(number): return False number = number // 10 return True
def is_trunc_left_to_right(number: int) -> bool: '''checks if a number is truncatable left to right while remaining prime''' while number > 0: if not is_prime(number): return False number = int(str(number)[1:]) if number >= 10 else 0 return True
def solve() -> str: '''Problem 46 - Goldbach's other conjecture''' n = 3 while True: if not is_prime(n): if not _goldbach.is_goldbach_number(n): break n += 2 return str(n)
def consecutive_primes(a: int, b: int) -> int: '''returns number of primes made from n^2 + an + b starting at n = 0''' assert isinstance(a, int) and isinstance(b, int) def formula(n: int) -> int: return n**2 + a * n + b n = 0 while is_prime(formula(n)): n += 1 return n
def solve() -> str: '''Problem 37 - Truncatable primes''' # start with 2, 3, 5, 7 # rightmost digit must be 2, 3, 5, 7 # primes with two or more digits in base ten, must end in 1, 3, 7, 9 # so when removing right to left each digit except leftmost must be one # of those known = set() stack = [2, 3, 5, 7] while len(stack) > 0: number = stack.pop() if is_truncatable_prime(number): known.add(number) if is_prime(number): for digit in {1, 3, 7, 9}: stack.append(append_digit(number, digit)) return str(sum(known))
def test_is_prime() -> None: assert is_prime(-1) is False assert is_prime(0) is False assert is_prime(1) is False assert is_prime(2) is True assert is_prime(3) is True assert is_prime(4) is False assert is_prime(5) is True assert is_prime(6) is False assert is_prime(7) is True assert is_prime(8) is False assert is_prime(9) is False assert is_prime(10) is False assert is_prime(11) is True assert is_prime(12) is False assert is_prime(13) is True assert is_prime(198) is False assert is_prime(199) is True assert is_prime(200) is False