File size: 1,886 Bytes
8f34e5f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | """neural_tile -- self-assembly grows Pascal's triangle mod 2 (Lucas' theorem).
The program is a set of square tiles whose binding rule is a threshold gate: a
tile attaches at a site when the summed strength of its matching glues meets the
temperature. With the XOR rule tile set, the crystal that grows is exactly the
Sierpinski triangle -- cell (x,y) is filled iff the binomial C(x+y, x) is odd,
which by Lucas' theorem is iff x AND y == 0. Every filled cell is verified
against that arithmetic. Computation as crystal growth.
python demos/neural_tile_pascal_lucas.py
"""
import os, sys, time
HERE = os.path.dirname(os.path.abspath(__file__))
REPO = os.path.dirname(HERE)
sys.path.insert(0, os.path.join(REPO, "src"))
import tile as T
if __name__ == "__main__":
N = 100
print("neural_tile: Pascal mod 2 by threshold-gated self-assembly")
print("=" * 60)
t0 = time.perf_counter()
ts = T.rule2_tileset(lambda w, s: w ^ s)
seed = T._row_col_seed([1] * (N + 1), [1] * (N + 1))
A, det = T.grow(ts, seed, tau=2, strength={}, bounds=(0, 0, N, N), max_tiles=200000)
dt = time.perf_counter() - t0
interior = [(x, y) for x in range(1, N + 1) for y in range(1, N + 1)]
grown = sum(1 for p in interior if p in A)
bad = 0
for (x, y) in interior:
v = 1 if A[(x, y)].N == "v1" else 0
lucas = 1 if (x & y) == 0 else 0 # C(x+y,x) odd <=> no carry in x+y
bad += (v != lucas)
print(f"grew {grown} rule tiles in {dt:.1f}s (directed={det}, "
f"{2 * N} anti-diagonals deep)")
print(f"tile(x,y) == [C(x+y,x) is odd] for all {len(interior)} cells: "
f"{'EXACT' if bad == 0 else f'{bad} MISMATCHES'}")
print("\ncorner of the assembly (30x30, '#' = odd binomial):")
for y in range(30, 0, -1):
print(" " + "".join("#" if A[(x, y)].N == "v1" else "." for x in range(1, 31)))
|