Euler discovered the remarkable quadratic formula:
$n^2 + n + 41$
It turns out that the formula will produce 40 primes for the consecutive integer values 0≤n≤39. However, when $n=40$, $40^2 + 40 + 41 = 40(40+1)+41$ is divisible by $41$, and certainly when $n=41,41^2+41+41$ is clearly divisible by 41.
The incredible formula $n^2−79n+1601$ was discovered, which produces 80 primes for the consecutive values 0≤n≤79. The product of the coefficients, $−79$ and $1601$, is $−126479$.
Considering quadratics of the form:
$n^2 + an +b$, where |a|<1000 and |b|≤1000
where |n| is the modulus/absolute value of n e.g. |11|=11 and |−4|=4.
Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n=0.
Okay, bruteforcing this complete thing is definitely hard. The interesting thing is that euler provided two examples. If we calculate the primes for both terms we see that there is a certain overlap. This indicates that there is a relation between the two. Sure enough if we put $n-40$ into the first term we get the following.
$(n - 40)^2 + (n - 40) + 41 = n^2 - 80n + 1600 + n - 40 + 41 = n^2 - 79n +1601$
Let's assume that all incredible formulas can be derived by inserting $(n - p)$ into the formula. Of course, what ever value we choose for p the resulting terms must not exceed the boundaries for a or b. We calculate the boundaries.
$(n-p)^2 + (n-p) + 41 = n^2 + n(-2p + 1) + p^2 - p + 41$
Where $(-2p + 1) = a$ and $p^2 -p + 41 = b$. We can now calulate the bounds for a:
$-2p + 1 > -1000 \rightarrow p < 500.5$
$-2 p + 1 < 1000 \rightarrow p > -499.5$
And b:
$p^2 - p + 41 <= 1000$
$-30.472 < p < 31.472$
$p^2 - p + 41 >= 1000$ True for $\forall p \in \mathbb{N}$
So now we only have to check for the values p in range(-30, 32). Alternatively, for the example $p = 40$ was used, maybe the next smaller value $p = 31$ yields the correct solution:
$s = a\times b = (-2 * 31 + 1) * (31^2 - 31 + 41) = -61 \times 971 = -59231$
from functools import lru_cache
@lru_cache(maxsize=1000)
def is_prime(n):
if n < 2:
return False
from math import sqrt
for s in range(2, int(sqrt(n) + 1)):
if n % s == 0:
return False
if s * s > n:
return True
return True
assert(is_prime(41) == True)
def get_quadratic(n, p):
return n*n + n * (-2* p + 1) + p*p - p + 41
n_max = 0
p_max = 0
for p in range(-30, 32):
for n in range(0, 10000):
if not is_prime(get_quadratic(n, p)) and n > n_max:
n_max = n
p_max = p
break
p = p_max
s = (-2 * p + 1) * (p*p - p + 41)
assert(s == -59231)
s