main.rs

3.5 kB · rust · 108 lines

1mod carpet;2mod census;3mod count;4mod design;5mod fit;6mod two;78use count::{arcs, glue, mirrors, series, void_block};9use design::Design;10use std::time::Instant;1112// CHECK1314fn check() {15    let (mut levels, mut images, mut voids, mut routes, mut bad) = (0, 0, 0, 0, 0);16    for (base, top) in [(2usize, 7usize), (3, 4)] {17        for code in 0..1u128 << (base * base) {18            let d = Design::full(code, base);19            let blocks = series(base, &d.tile, top);20            for level in 0..=top {21                let (side, on) = d.cells(level);22                let (loops, strands) = arcs(side, &on);23                let euler = mirrors(side, &on);24                levels += 1;25                if loops as u128 != blocks[level]26                    || euler != loops as i6427                    || strands != 2 * side as u6428                {29                    bad += 1;30                    println!("mismatch {} level {level}: arcs {loops}/{strands}, mirrors {euler}, blocks {}", d.name(), blocks[level]);31                }32            }33            for g in 1..4 {34                images += 1;35                if series(base, &d.image(g).tile, top) != blocks {36                    bad += 1;37                    println!("symmetry {g} breaks {}", d.name());38                }39            }40        }41    }42    for n in 2..6 {43        let mut s = 1;44        while s * n <= 3000 {45            let glued = glue(n, &vec![true; n * n], &void_block(s), true);46            voids += 1;47            if glued.partner != void_block(s * n).partner || glued.loops != 0 {48                bad += 1;49                println!("void block differs at base {n} side {s}");50            }51            s *= n;52        }53    }54    for (code, n) in [55        (7u128, 3usize),56        (14, 3),57        (11, 3),58        (13, 3),59        (6, 3),60        (9, 3),61        (7, 4),62        (7, 5),63    ] {64        let parity = Design::new(code, n, 2);65        let full = Design::full(parity.full_code(), n);66        for level in 0..=3 {67            routes += 1;68            if parity.cells(level) != full.cells(level) {69                bad += 1;70                println!("parity route differs on {}", parity.name());71            }72        }73    }74    println!("CHECK every code at base 2 to level 7 and at base 3 to level 4");75    println!("  union-find over midpoints = mirror cycle rank = block recursion, strands = 2 side: {levels} levels");76    println!("  half turn, transpose, anti-transpose give the same loop sequence: {images} images");77    println!("  glued void block = formula, no loop: {voids} sides at bases 2 to 5");78    println!("  parity name and full code build the same cells: {routes} levels");79    println!("  mismatches: {bad}");80}8182fn main() {83    let verb = std::env::args().nth(1).unwrap_or_else(|| "all".to_string());84    let clock = Instant::now();85    if verb == "check" || verb == "all" {86        check();87    }88    if verb == "two" || verb == "all" {89        two::two();90    }91    if verb == "carpet" || verb == "all" {92        carpet::carpet();93    }94    if verb == "bases" || verb == "all" {95        census::bases();96    }97    if verb == "lengths" || verb == "all" {98        census::lengths(3, 12, &[495, 43, 181, 175, 171]);99    }100    if verb == "gains" || verb == "all" {101        census::gains();102    }103    if verb == "census" || verb == "all" {104        census::census(2, 24, 24, &(0..16).collect::<Vec<u128>>());105        census::census(3, 14, 17, &(0..512).collect::<Vec<u128>>());106    }107    println!("time {:.1} s", clock.elapsed().as_secs_f64());108}