Quadratic Primes
Considering quadratics of the form n^2 + an + b where |a| < 1000 and |b| <= 1000, find the product of the coefficients a and b that produces the maximum number of primes for consecutive values of n...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
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 \le n \le 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 \le n \le 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| \le 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\).
Problem 27: Quadratic Primes
Mathematical Development
Definition 1. For integers , define . The prime chain length of is .
Lemma 1 (Necessity of Prime). If , then is a positive prime.
Proof. Evaluating at gives . For to be prime, we need .
Lemma 2 (Parity Constraint). If is an odd prime and , then is odd.
Proof. We require to be prime. Since is odd, has the same parity as . If is even, then is even, so is the only possibility, forcing . But then for , contradicting . For : , (prime), (not prime), giving . This is a short chain. For long chains with , we need odd.
Lemma 3 (Lower Bound on ). If , then .
Proof. We need , so , i.e., .
Theorem 1 (Connection to Heegner Numbers). Euler’s quadratic produces primes for . This is intimately connected to the fact that is a Heegner number.
Proof. The discriminant of is . By the Stark—Heegner theorem, the imaginary quadratic field has class number , meaning its ring of integers is a principal ideal domain (and hence a unique factorization domain). In the theory of binary quadratic forms, class number 1 implies that the principal form is the unique reduced form of discriminant . By Rabinowitz’s theorem (1913), a quadratic produces primes for if and only if the class number . Since and , the quadratic is prime for .
Remark. The quadratic is a reindexing of Euler’s polynomial, producing 80 primes for .
Theorem 2 (Optimal Coefficients). Among all with and , the pair maximizing is , with . The product is .
Proof. By exhaustive search. The search space is constrained as follows:
- By Lemma 1, ranges over the 168 primes in .
- By Lemma 2, for odd , only odd values of are tested.
- By Lemma 3, .
For each admissible , we evaluate for until a composite or negative value is reached. Primality is checked via a precomputed sieve. The maximum chain length found is , achieved uniquely at . The discriminant of is , confirming the connection to the Heegner number .
Editorial
We search over the admissible coefficient pairs using number-theoretic pruning. Because must be prime, we only enumerate prime values of , precompute a prime sieve large enough for all tested values, and then scan the allowed range of while skipping parity patterns that cannot produce long prime runs. For each pair we count consecutive values of starting from 0 until stops being prime, and we keep the product for the longest run. This is sufficient because every candidate pair in the search region is either tested or eliminated by a necessary condition.
Pseudocode
Algorithm: Quadratic Polynomial Producing the Longest Prime Run
Require: Bounds A and B for the coefficients.
Ensure: The product ab for the coefficient pair maximizing the number of consecutive prime values of n^2 + an + b starting at n = 0.
1: Build a prime table large enough for all values tested, and enumerate the admissible prime values of b.
2: Initialize best_run ← 0 and best_pair ← (0, 0).
3: For each candidate pair (a, b) with |a| < A and prime b ≤ B, count the consecutive integers n ≥ 0 for which n^2 + an + b is positive and prime.
4: If this count exceeds best_run, update best_run ← count and best_pair ← (a, b).
5: Return the product of the two entries of best_pair.
Complexity Analysis
Proposition (Time Complexity). The algorithm runs in time, where is the number of candidate primes, is the range of (halved by parity pruning for odd ), and is the maximum chain length. Total: operations.
Proof. The outer loops enumerate at most pairs. For each pair, the inner loop runs at most iterations, each performing an sieve lookup.
Proposition (Space Complexity). The algorithm uses space where is the sieve size. We need to test values up to approximately , so .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main() {
const int LIMIT = 1000000;
vector<bool> is_prime(LIMIT + 1, true);
is_prime[0] = is_prime[1] = false;
for (int i = 2; i * i <= LIMIT; i++)
if (is_prime[i])
for (int j = i * i; j <= LIMIT; j += i)
is_prime[j] = false;
auto check_prime = [&](int n) -> bool {
if (n < 2) return false;
if (n <= LIMIT) return is_prime[n];
for (int i = 2; (long long)i * i <= n; i++)
if (n % i == 0) return false;
return true;
};
int best_a = 0, best_b = 0, best_count = 0;
for (int b = 2; b <= 1000; b++) {
if (!is_prime[b]) continue;
for (int a = -999; a < 1000; a++) {
int n = 0;
while (check_prime(n * n + a * n + b))
n++;
if (n > best_count) {
best_count = n;
best_a = a;
best_b = b;
}
}
}
cout << (long long)best_a * best_b << endl;
return 0;
}
def solve():
LIMIT = 1000000
is_prime = [True] * (LIMIT + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(LIMIT**0.5) + 1):
if is_prime[i]:
for j in range(i * i, LIMIT + 1, i):
is_prime[j] = False
def check_prime(n):
if n < 2:
return False
if n < len(is_prime):
return is_prime[n]
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
primes_b = [p for p in range(2, 1001) if is_prime[p]]
best_a, best_b, best_count = 0, 0, 0
for b in primes_b:
for a in range(-999, 1000):
n = 0
while check_prime(n * n + a * n + b):
n += 1
if n > best_count:
best_count = n
best_a, best_b = a, b
print(best_a * best_b)
if __name__ == "__main__":
solve()