"""dual2i.py -- do the two ends of base 2i exchange what they read? QUESTION. Base 2i, digits 0..3. The two-ends law of base b says depth j of the trailing end reads m exactly where span j at the leading end hides it exactly: one condition, m | b^j. Does it carry to the residue rings of Z[2i], the integers base 2i writes? THE ARGUMENT (written before the engine). (1) THE DIGITS. (2i)^(2k) = (-4)^k and (2i)^(2k+1) = 2i(-4)^k, so sum d_k (2i)^k = a + 2bi, a the even places read in base -4 and b the odd ones. Base -4 with digits 0..3 writes every integer once, so base 2i writes Z[2i] = {x + 2yi} once each; coordinates (x, y). (2) THE TILES. A base -4 tile of j digits is 4^j consecutive integers, so the span-j leading tile is a translate of the box [0, A) x [0, B), A = 4^ceil(j/2), B = 4^floor(j/2), and the depth-j trailing tile is a coset of (2i)^j Z[2i] = AZ x BZ. (3) THE CRITERION. An ideal I of Z[2i] is a lattice closed under T(x, y) = (-4y, x), multiplication by 2i. READ at depth j iff (2i)^j is in I iff every character (alpha, beta) of Z^2/I has A alpha and B beta in Z. HIDDEN at span j iff every nontrivial character sums to 0 on the box, the sum a product of two geometric sums: A alpha in Z with alpha not, or B beta in Z with beta not. So read implies hidden at the same j; on one axis they coincide, and a character killed by one axis alone splits them. (4) THE WITNESS. Z[2i] -> Z/8, 2i -> 2 (2^2 + 4 = 8), kernel I8 = {x + 2y = 0 mod 8}: its characters (s/8, 2s/8) die on the 4 x 4 box by beta at odd s and by alpha at even s, so I8 is hidden from span 2, and (2i)^2 -> 4, (2i)^3 -> 0 read it from depth 3. For mZ[2i] the characters (1/m, 0) and (0, 1/m) need both axes. PREDICTIONS (frozen before the engine). C1 strings of length <= 8 hit distinct points of Z[2i], and every span-j leading tile of a string of length 7 or 8, leading digit nonzero, is a translate of the A x B box. C2 one axis: the same counter says an interval of 4^j hides m iff m | 4^j, m = 2..64, j = 0..4. P1 read at depth j implies hidden at span j, every ideal of index <= 256 and j = 0..6. P2 hidden by box count iff the character criterion, the same range. P3 I8 hidden from span 2, read from depth 3. P4 I = mZ[2i]: least span = least depth, every m <= 16. P5 least depth - least span >= 0 at every ideal of 2-power index, > 0 at some (the gap's distribution printed); an ideal whose index has an odd prime is neither read nor hidden at j <= 6. Planted break: the criterion with A and B swapped must miss P2. KILL (frozen). "The two-ends law carries to base 2i as one condition" dies if an ideal of 2-power index prints a least span different from its least depth. The character reading dies if P2 prints a disagreement. C1 and C2 are read first; a red control voids the run. FINDINGS (entered after the run, from its printed output). C both controls green: 65536 strings of length <= 8 hit distinct points; 81915 leading tiles at lengths 7 and 8, j = 0..6, are each a translate of the A x B box; on one axis 4^j consecutive integers hide m iff m | 4^j at every m = 2..64, j = 0..4. P1 read implies hidden at every ideal and j, 0 off; 297 ideals of index <= 256, 23 of 2-power index. P2 the box count and the character criterion agree, 0 off; the plant (A and B swapped) disagrees 8 times. P3 I8 = (8, 0), (6, 1): least span 2, least depth 3. P4 mZ[2i], m <= 16: least span = least depth, 0 off (at odd m both are none to j = 6, so P4 reads the even m). P5 least depth - least span over the 23 ideals of 2-power index: 0 at 13, 1 at 10, never negative, no 'beyond 6' key printed; an odd prime in the index: neither read nor hidden, 0 off. The least split ideal is (4, 0), (2, 1), {x + 2y = 0 mod 4}, index 4: hidden at span 1, read at depth 2. K KILL FIRES on one condition: the ends part at 10 ideals. RUN RECORD. 10 checks, 0.6 s. Rerun bare: 10/10 checks, 0.6 s, 44.1 MB. """ import sys from fractions import Fraction from itertools import product CHECKS = [] JMAX = 6 NMAX = 256 def check(name, ok, detail=""): CHECKS.append(bool(ok)) print(f" {'PASS' if ok else 'FAIL'} {name}" + (f" ({detail})" if detail else "")) def section(title): print() print(title) def box(j): """The span-j leading box: A = 4^ceil(j/2), B = 4^floor(j/2).""" return 4 ** ((j + 1) // 2), 4 ** (j // 2) def point(digits): """sum d_k (2i)^k, digits least significant first, as (x, y).""" re = im = 0 pr, pi = 1, 0 for d in digits: re, im = re + d * pr, im + d * pi pr, pi = -2 * pi, 2 * pr assert im % 2 == 0 return re, im // 2 class Lattice: """L = Z(a, 0) + Z(c, d), 0 <= c < a: every full-rank sublattice of Z^2 once.""" def __init__(self, a, c, d): self.a, self.c, self.d = a, c, d self.n = a * d def __contains__(self, v): x, y = v if y % self.d: return False return (x - (y // self.d) * self.c) % self.a == 0 def key(self, x, y): q, r = divmod(y, self.d) return (x - q * self.c) % self.a, r def ideal(self): return (0, self.a) in self and (-4 * self.d, self.c) in self def characters(self): """The dual L* modulo Z^2, from M^-1 with M's rows the basis.""" a, c, d = self.a, self.c, self.d w1 = (Fraction(1, a), Fraction(-c, a * d)) w2 = (Fraction(0), Fraction(1, d)) out = set() for k1 in range(a): for k2 in range(d): al = (k1 * w1[0] + k2 * w2[0]) % 1 be = (k1 * w1[1] + k2 * w2[1]) % 1 out.add((al, be)) assert len(out) == self.n return out def ideals(nmax): for a in range(1, nmax + 1): for d in range(1, nmax // a + 1): for c in range(a): L = Lattice(a, c, d) if L.ideal(): yield L def power(j): v = (1, 0) for _ in range(j): v = (-4 * v[1], v[0]) return v def read_at(L, j): return power(j) in L def hidden_by_count(L, A, B): if (A * B) % L.n: return False counts = {} for x in range(A): for y in range(B): k = L.key(x, y) counts[k] = counts.get(k, 0) + 1 return len(counts) == L.n and len(set(counts.values())) == 1 def hidden_by_characters(chars, A, B): for al, be in chars: if al == 0 and be == 0: continue if not ((al != 0 and (A * al) % 1 == 0) or (be != 0 and (B * be) % 1 == 0)): return False return True def least(pred): return next((j for j in range(JMAX + 1) if pred(j)), None) def two_power(n): return n & (n - 1) == 0 def section_controls(): section("C controls: the digit map and the tiles; one axis") seen, clash = {}, 0 for L in range(0, 9): for ds in product(range(4), repeat=L): if L and ds[-1] == 0: continue p = point(ds) clash += p in seen seen[p] = ds bad = tiles = 0 for L in (7, 8): for j in range(0, JMAX + 1): A, B = box(j) groups = {} for ds in product(range(4), repeat=L): if ds[-1] == 0: continue groups.setdefault(ds[j:], []).append(point(ds)) for pts in groups.values(): tiles += 1 x0 = min(p[0] for p in pts) y0 = min(p[1] for p in pts) want = {(x0 + x, y0 + y) for x in range(A) for y in range(B)} bad += set(pts) != want check("C1 strings of length <= 8 hit distinct points", clash == 0, f"{len(seen)} points, {clash} clashes") check("C1 every span-j leading tile is a translate of the A x B box", bad == 0, f"{tiles} tiles at lengths 7, 8 and j = 0..6, " f"{bad} off") off = 0 for m in range(2, 65): L = Lattice(m, 0, 1) for j in range(5): off += hidden_by_count(L, 4 ** j, 1) != (4 ** j % m == 0) check("C2 one axis: 4^j consecutive integers hide m iff m | 4^j", off == 0, f"m = 2..64, j = 0..4, {off} off") return clash == 0 and bad == 0 and off == 0 def section_ideals(): section(f"P every ideal of Z[2i] of index <= {NMAX}, j = 0..{JMAX}") all_ideals = list(ideals(NMAX)) two = [L for L in all_ideals if two_power(L.n)] print(f" {len(all_ideals)} ideals, {len(two)} of 2-power index") p1 = p2 = plant = 0 rows = [] for L in all_ideals: hid, red = [], [] chars = L.characters() for j in range(JMAX + 1): A, B = box(j) h = hidden_by_count(L, A, B) r = read_at(L, j) p1 += r and not h p2 += h != hidden_by_characters(chars, A, B) plant += h != hidden_by_characters(chars, B, A) hid.append(h) red.append(r) rows.append((L, least(lambda j: hid[j]), least(lambda j: red[j]))) check("P1 read at depth j implies hidden at span j", p1 == 0, f"{p1} off") check("P2 hidden by count iff the character criterion", p2 == 0, f"{p2} off") check("Bp the plant (A and B swapped) misses P2", plant > 0, f"{plant} disagreements") return rows def section_split(rows): section("P3-P5 where the two ends part") by = {(L.a, L.c, L.d): (s, t) for L, s, t in rows} s, t = by[(8, 6, 1)] print(f" I8 = (8, 0), (6, 1): least span {s}, least depth {t}") check("P3 I8 hidden from span 2, read from depth 3", (s, t) == (2, 3)) off = 0 for m in range(1, 17): s, t = by[(m, 0, m)] off += s != t check("P4 mZ[2i]: least span = least depth, m <= 16", off == 0, f"{off} off") gaps, neg, odd = {}, 0, 0 for L, s, t in rows: if two_power(L.n): if s is None or t is None: gaps["beyond 6"] = gaps.get("beyond 6", 0) + 1 continue neg += t < s gaps[t - s] = gaps.get(t - s, 0) + 1 else: odd += s is not None or t is not None print(f" 2-power index, least depth - least span: " f"{dict(sorted(gaps.items(), key=str))}") check("P5 the gap is >= 0 everywhere and > 0 somewhere", neg == 0 and any(isinstance(g, int) and g > 0 for g in gaps), f"{neg} negative") check("P5 an odd prime in the index: neither read nor hidden", odd == 0, f"{odd} off") print(" 2-power index <= 64: (a, c, d) index span depth") for L, s, t in rows: if two_power(L.n) and L.n <= 64: mark = " <-- splits" if s != t else "" print(f" ({L.a}, {L.c}, {L.d}) {L.n:>4} {s} {t}{mark}") return gaps def main(): if not section_controls(): print(" a red control voids the run") return 1 rows = section_ideals() gaps = section_split(rows) section("K the kill") split = sum(v for g, v in gaps.items() if isinstance(g, int) and g > 0) print(f" ideals of 2-power index where the ends part: {split}; " f"one condition {'DIES' if split else 'HOLDS'}") print() print(f"{sum(CHECKS)}/{len(CHECKS)} checks pass") return 0 if all(CHECKS) else 1 if __name__ == "__main__": sys.exit(main())