def semidivisible_numbers(limit): """ >>> list(semidivisible_numbers(1000)) [8, 10, 12, 18, 20, 21, 24, 28, 30, 40, 42, 45, 55, 56, 63, 66, 70, 84, 88, 91, 98, 99, 105, 110, 112, 119, 130, 132, 154, 156, 165, 170, 182, 187, 195, 204, 208, 234, 238, 247, 255, 260, 272, 273, 286, 304, 306, 340, 342, 357, 368, 380, 391, 399, 414, 418, 456, 460, 475, 483, 494, 506, 513, 551, 552, 575, 580, 598, 609, 621, 638, 644, 690, 696, 713, 725, 736, 754, 759, 782, 783, 805, 812, 828, 868, 870, 928, 930, 957, 962, 992, 999] >>> len(_) 92 """ for lps, ups in zip(primes(), islice(primes(), 1, None)): lo = lps**2 hi = ups**2 hi_candidates = set() lo_candidates = set() c = hi - ups while c > lo: hi_candidates.add(c) c -= ups c = lo + lps while c < hi: lo_candidates.add(c) c += lps candidates = lo_candidates.symmetric_difference(hi_candidates) for c in sorted(list(candidates)): if c > limit: return yield c
def search(goal): """ >>> search(6) 13 >>> search(7) 56003 """ already_searched = set() for prime in primes(): if prime in already_searched: continue positions_list = list(position_combinations(prime)) for positions in positions_list: digits = list(digits_of(prime)) family = set() for digit in range(10): if 0 in positions and digit == 0: continue for pos in positions: digits[pos] = digit number = from_digits(digits) if is_prime(number): already_searched.add(number) family.add(number) if len(family) >= goal: return min(family)
def decompose_prime_square(n): """ Attempt to write n as the sum of a prime and twice a square. >>> decompose_prime_square(9) (7, 1) >>> decompose_prime_square(15) (7, 2) >>> decompose_prime_square(21) (3, 3) >>> decompose_prime_square(25) (7, 3) >>> decompose_prime_square(27) (19, 2) >>> decompose_prime_square(33) (31, 1) """ for p in up_to(n, primes()): if p == 2: continue residue = n - p assert residue % 2 == 0, residue square = residue // 2 if is_perfect_square(square): return (p, isqrt(square))
def prime_sequence_sums(limit): prime_list = [] for p in primes(): prime_list.append(p) if sum(prime_list) >= limit: return for i in range(len(prime_list)): sequence = prime_list[i:] if len(sequence) <= 1: continue s = sum(sequence) if is_prime(s): yield sequence, s
def truncatable_primes(): seen_primes = set() one_digit_primes = (2, 3, 5, 7) for p in primes(): seen_primes.add(p) digits = digits_of(p) # One-digit primes are not considered truncatable. if len(digits) == 1: continue # All digits besides the first must be odd. if not all(d % 2 == 1 for d in digits[1:]): continue # First and last digit must be prime. if digits[0] not in one_digit_primes or \ digits[-1] not in one_digit_primes: continue # Test whether each truncation is a prime. truncs = sorted(list(from_digits(d) for d in truncations(digits))) if all(t in seen_primes for t in truncs): yield p
def testZip(self): from utility import primes zipped_primes = list(zip(primes(), itertools.islice(primes(), 1, 5))) self.assertEqual(zipped_primes, [(2, 3), (3, 5), (5, 7), (7, 11)])
def testParallelIteration(self): from utility import primes p1, p2 = primes(), primes() self.assertEqual([next(p1) for i in range(3)], [2, 3, 5]) self.assertEqual([next(p2) for i in range(6)], [2, 3, 5, 7, 11, 13]) self.assertEqual([next(p1) for i in range(3)], [7, 11, 13])
def testCaching(self): from utility import primes p1 = list(itertools.islice(primes(), 100)) p2 = list(itertools.islice(primes(), 100)) self.assertEqual(p1, p2)
# The minimum totient compared to the size of n will always be from the product # of successive primes. from utility import primes limit = 1000000 last = None result = 1 for p in primes(): result *= p if result > limit: print(last) break last = result
for c in coefficients: value = value * x + c return value def prime_sequence_length(coefficients): """ Find the length of the prime sequence generated by a polynomial. >>> prime_sequence_length((1, 1, 41)) 40 >>> prime_sequence_length((1, -79, 1601)) 80 """ for n in itertools.count(): if not is_prime(eval_polynomial(coefficients, n)): return n # We only need to check prime b, because we evaluate an n = 0, where the value == b. MAX_NUM = 1000 - 1 max_poly = None max_length = 0 for a in range(-MAX_NUM, MAX_NUM + 1): for b in up_to(MAX_NUM, primes()): poly = (1, a, b) l = prime_sequence_length(poly) if l > max_length: max_poly = poly max_length = l _, max_a, max_b = max_poly print(max_a * max_b)
from utility import nth, primes print(nth(10001 - 1, primes()))
from utility import primes, digits_of, up_to # In order to maximize the totient, we need to look for "sharp" numbers, having # few prime factors, with those factors being large. limit = 10**7 solutions = [] seen_primes = [] for a in up_to(limit // 2, primes()): for b in seen_primes: n = a * b if n > limit: break t = n t -= t // a if a != b: t -= t // b if sorted(digits_of(n)) == sorted(digits_of(t)): solutions.append((n, n / t)) seen_primes.append(a) solutions.sort(key=lambda x: x[1]) print(min(solutions, key=lambda x: x[1])[0])
def circular_primes(limit): prime_set = set(up_to(limit, primes())) for p in prime_set: if all((r in prime_set) for r in rotations(p)): yield p