project-euler/357_prime_generating_intege...

55 lines
1.2 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
from itertools import combinations
from operator import mul
def candidates(sieve):
n = len(sieve)
for i in range(4, n, 4):
sieve[i] = True
for p in range(3, n, 2):
if sieve[p]:
continue
for i in range(p**2, n, 2*p):
sieve[i] = p
for i in range(2*p**2, n, 2*p**2):
sieve[i] = True
if not sieve[p-1]:
yield p-1
def is_prime(n):
return not sieve[n] and n%2
def factors(n):
r = []
while not n%2:
r.append(2)
n //= 2
while sieve[n] != False:
r.append(sieve[n])
n //= sieve[n]
return r + [n]
def test_alt(n):
fctrs = [f for f in factors(n)]
for i in range(len(fctrs)//2):
for c in combinations(fctrs, i+1):
d = reduce(mul, c)
if not is_prime(d + n//d):
return False
return True
def test(n, fctrs, p=1, i=0, depth=1):
if depth > len(fctrs) // 2:
return True
for j, f in enumerate(fctrs[i:]):
if not is_prime(p*f + n//(p*f)) or not test(n, fctrs, p*f, j+1, depth+1):
return False
return True
N = 10**8 + 2
sieve = [False] * N
print(sum(c for c in candidates(sieve) if test(c, factors(c))) + 1)