55 lines
1.2 KiB
Python
55 lines
1.2 KiB
Python
#!/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)
|