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)))