Project Euler Problem 574
Let q be a prime and A ge B 0 be two integers with the following properties: - A and B have no prime factor in common, t
Solution
Answer: 5780447552057000454
Let
$$P(q)=\prod_{r<q,\ r\text{ prime}} r$$
(the primorial over primes smaller than $q$).
We seek the minimum $A$ such that for a prime $p$,
$$p=A+B \quad \text{or} \quad p=A-B,$$
with:
- $\gcd(A,B)=1$,
- every prime $r<q$ divides $AB$,
- $p<q^2$.
Because $\gcd(A,B)=1$, every prime $r<q$ divides exactly one of $A,B$. Thus for each such prime $r$,
$$A \equiv 0 \pmod r \quad\text{or}\quad A \equiv p \pmod r,$$
since in both sum and difference cases, $B\equiv p-A$ or $A-p$, giving the same congruence condition modulo $r$.
So for fixed $q$, $A$ is determined by a system of congruences:
$$A \equiv \varepsilon_r \pmod r, \qquad \varepsilon_r\in{0,p}.$$
By the Chinese Remainder Theorem, each assignment gives a unique residue class modulo $P(q)$.
For each CRT residue $x$, the valid candidates are:
- sum case $p=A+B$:
$A\in[\lceil p/2\rceil,p)$, $A\equiv x\pmod{P(q)}$,
- difference case $p=A-B$:
$A>p$, $A\equiv x\pmod{P(q)}$.
We recursively build the CRT solution prime-by-prime and keep the smallest feasible $A$.
The following Python computes $V(p)$ and then
$$S(3800)=\sum_{p<3800}V(p).$$
from math import gcd, isqrt
def sieve(n):
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, isqrt(n) + 1):
if is_prime[i]:
for j in range(i * i, n + 1, i):
is_prime[j] = False
return [i for i in range(n + 1) if is_prime[i]
primes = sieve(100)
# primes less than q
primes_below_q = {
q: [r for r in primes if r < q]
for q in primes
}
def V(p):
best = float('inf')
for q in primes:
if q * q <= p:
continue
ps = primes_below_q[q]
def dfs(i, x, modulus):
nonlocal best
# pruning
if x >= best:
return
# finished CRT construction
if i == len(ps):
# ----- sum case: p = A + B -----
low = (p + 1) // 2
A = x
if A < low:
A += ((low - A + modulus - 1) // modulus) * modulus
if A < p and gcd(A, p) == 1:
best = min(best, A)
# ----- difference case: p = A - B -----
A = x
if A <= p:
A += ((p + 1 - A + modulus - 1) // modulus) * modulus
if gcd(A, p) == 1:
best = min(best, A)
return
r = ps[i]
inv = pow(modulus % r, -1, r)
target = p % r
# A ≡ 0 (mod r)
k = ((-x) % r) * inv % r
dfs(i + 1, x + modulus * k, modulus * r)
# A ≡ p (mod r)
k = ((target - x) % r) * inv % r
dfs(i + 1, x + modulus * k, modulus * r)
dfs(0, 0, 1)
return best
def S(n):
return sum(V(p) for p in sieve(n - 1))
print(S(10)) # 10
print(S(200)) # 7177
print(S(3800))
Verification:
- $S(10)=10$ ✔️
- $S(200)=7177$ ✔️
- $V(37)=22$ ✔️
- $V(151)=165$ ✔️
Therefore,
Answer: 302121311939