Pseudo-Fortunate Numbers
An integer n is admissible if n = 2^(a_1) 3^(a_2) 5^(a_3)... p_k^(a_k) where 2 = p_1 < p_2 = 3 <... < p_k are consecutive primes and all exponents a_i >= 1. For an admissible number n, the pseudo-F...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
An even positive integer \(N\) will be called admissible, if it is a power of \(2\) or its distinct prime factors are consecutive primes.
The first twelve admissible numbers are \(2,4,6,8,12,16,18,24,30,32,36,48\).
If \(N\) is admissible, the smallest integer \(M > 1\) such that \(N+M\) is prime, will be called the pseudo-Fortunate number for \(N\).
For example, \(N=630\) is admissible since it is even and its distinct prime factors are the consecutive primes \(2,3,5\) and \(7\).
The next prime number after \(631\) is \(641\); hence, the pseudo-Fortunate number for \(630\) is \(M=11\).
It can also be seen that the pseudo-Fortunate number for \(16\) is \(3\).
Find the sum of all distinct pseudo-Fortunate numbers for admissible numbers \(N\) less than \(10^9\).
Problem 293: Pseudo-Fortunate Numbers
Mathematical Foundation
Theorem 1 (Structure of Admissible Numbers). The set of admissible numbers is finite and can be generated recursively. The consecutive primes used are since the primorial , while .
Proof. An admissible number must include all consecutive primes from 2 up to some prime with exponents . The minimum admissible number using primes is the primorial . Since and , admissible numbers use consecutive primes up to at most 23. The total count of admissible numbers is , which is bounded and equals a few thousand in practice.
Lemma 1 (Bertrand’s Postulate Bound). For any admissible number , the pseudo-Fortunate number satisfies , and in practice by the prime number theorem.
Proof. By Bertrand’s postulate, there exists a prime in , so . More precisely, by the prime number theorem, the expected gap after is , so is typically small (on the order of ).
Lemma 2 (Pseudo-Fortunate Numbers are Likely Prime). For all admissible , is itself prime.
Proof. Suppose is composite, say with . Then and we need to check if could be prime. Since is divisible by all small primes up to , and , if is divisible by any prime , then is also divisible by that prime (since and implies ), so is composite. However, if has no prime factor , this argument fails. Nevertheless, empirically for this problem, all pseudo-Fortunate numbers are indeed prime. This is a conjecture (related to Fortune’s conjecture) rather than a proven theorem.
Editorial
An admissible number uses consecutive primes starting from 2, each at least once. The pseudo-Fortunate number for n is the smallest m > 1 such that n + m is prime. We recursive generation of admissible numbers. We then compute pseudo-Fortunate numbers. Finally, iterate over n in admissible.
Pseudocode
Recursive generation of admissible numbers
Compute pseudo-Fortunate numbers
for n in admissible
Complexity Analysis
- Time: where is the number of admissible numbers (a few thousand), is the average gap to the next prime, and is the cost of trial-division primality testing. With Miller—Rabin, the per-test cost drops to .
- Space: for storing admissible numbers and for the set of distinct pseudo-Fortunate numbers.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll LIMIT = 1000000000LL;
// Small primes for generating admissible numbers
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
int nprimes = 10;
vector<ll> admissible;
// Generate all admissible numbers <= LIMIT
// An admissible number uses consecutive primes starting from 2, each at least once
void gen_admissible(int idx, ll val) {
admissible.push_back(val);
if (idx >= nprimes) return;
ll p = primes[idx];
ll v = val * p;
while (v <= LIMIT) {
gen_admissible(idx + 1, v);
if (v > LIMIT / p) break;
v *= p;
}
}
// Miller-Rabin primality test
typedef unsigned long long ull;
typedef __int128 lll;
ull mulmod(ull a, ull b, ull m) {
return (lll)a * b % m;
}
ull powmod(ull a, ull b, ull m) {
ull res = 1; a %= m;
while (b > 0) {
if (b & 1) res = mulmod(res, a, m);
a = mulmod(a, a, m);
b >>= 1;
}
return res;
}
bool is_prime(ull n) {
if (n < 2) return false;
if (n < 4) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
ull d = n - 1;
int r = 0;
while (d % 2 == 0) { d /= 2; r++; }
for (ull a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) {
if (a >= n) continue;
ull x = powmod(a, d, n);
if (x == 1 || x == n - 1) continue;
bool found = false;
for (int i = 0; i < r - 1; i++) {
x = mulmod(x, x, n);
if (x == n - 1) { found = true; break; }
}
if (!found) return false;
}
return true;
}
int main() {
// Generate admissible numbers
// Start with prime index 0 (must include 2)
gen_admissible(1, 2); // val=2, next prime index=1 (prime 3)
// But also need to allow increasing exponents of prime 2
// Actually gen_admissible starts: idx=0 means we multiply by primes[0]=2.
// Let me fix: start with val=1, idx=0.
admissible.clear();
// gen_admissible(idx, val): val already includes primes[0..idx-1].
// Now try adding primes[idx]^k for k >= 1.
// Start: val=1, idx=0. Must add at least 2^1.
// Re-implement:
function<void(int, ll)> gen = [&](int idx, ll val) {
if (idx > 0) admissible.push_back(val); // val uses primes[0..idx-1]
if (idx >= nprimes) return;
ll p = primes[idx];
ll v = val * p;
while (v <= LIMIT) {
gen(idx + 1, v);
if (v > LIMIT / p) break;
v *= p;
}
};
gen(0, 1);
// Find pseudo-Fortunate numbers
set<ll> pf_set;
for (ll n : admissible) {
for (ll m = 2; ; m++) {
if (is_prime(n + m)) {
pf_set.insert(m);
break;
}
}
}
ll sum = 0;
for (ll m : pf_set) sum += m;
cout << sum << endl;
return 0;
}
"""
Problem 293: Pseudo-Fortunate Numbers
Find the sum of all distinct pseudo-Fortunate numbers for admissible numbers <= 10^9.
An admissible number uses consecutive primes starting from 2, each at least once.
The pseudo-Fortunate number for n is the smallest m > 1 such that n + m is prime.
"""
from sympy import isprime
LIMIT = 10**9
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
def gen_admissible():
"""Generate all admissible numbers <= LIMIT."""
result = []
def gen(idx, val):
if idx > 0:
result.append(val)
if idx >= len(primes):
return
p = primes[idx]
v = val * p
while v <= LIMIT:
gen(idx + 1, v)
v *= p
gen(0, 1)
return result
def solve():
admissible = gen_admissible()
pf_set = set()
for n in admissible:
m = 2
while not isprime(n + m):
m += 1
pf_set.add(m)
print(sum(pf_set))
if __name__ == "__main__":
solve()