carpet.rs

2.7 kB · rust · 82 lines

1use crate::census::describe;2use crate::count::{arcs, blocks, mirrors, series};3use crate::design::Design;4use std::time::Instant;56fn law(n: u32) -> i128 {7    (8i128.pow(n) - 1) / 7 - 3i128.pow(n) + n as i128 + 18}910fn lemma(n: u32) -> Vec<u32> {11    let side = 3usize.pow(n);12    let all: Vec<usize> = (0..=n).map(|j| (3usize.pow(j) - 1) / 2).collect();13    let mut turns: Vec<(usize, usize)> = Vec::new();14    for level in 0..n as usize {15        let s = 3usize.pow(level as u32);16        let mut next = Vec::new();17        for j in 0..3 {18            next.extend(turns.iter().map(|&(a, b)| (j * s + a, j * s + b)));19        }20        for j in 1..3 {21            next.extend(all[..level].iter().map(|&a| (j * s - 1 - a, j * s + a)));22        }23        turns = next;24    }25    let (b, r, t, l) = (0, side, 2 * side, 3 * side);26    let mut p = vec![u32::MAX; 4 * side];27    let mut tie = |x: usize, y: usize| {28        p[x] = y as u32;29        p[y] = x as u32;30    };31    for (k, &a) in all.iter().enumerate() {32        tie(b + a, l + a);33        tie(r + side - 1 - a, t + side - 1 - a);34        if k < n as usize {35            tie(b + side - 1 - a, r + a);36            tie(l + side - 1 - a, t + a);37        }38    }39    for &(x, y) in &turns {40        for o in [b, r, t, l] {41            tie(o + x, o + y);42        }43    }44    p45}4647pub fn carpet() {48    let d = Design::new(7, 3, 2);49    println!("CARPET {}, kept {}", d.name(), d.kept());50    for level in 0..=7 {51        let clock = Instant::now();52        let (side, on) = d.cells(level);53        let (loops, strands) = arcs(side, &on);54        let euler = mirrors(side, &on);55        println!("  level {level}: side {side}, arcs loops {loops}, strands {strands}, mirror cycle rank {euler}, law {}, {:.2} s", law(level as u32), clock.elapsed().as_secs_f64());56    }57    let s = series(3, &d.tile, 15);58    let ok = s59        .iter()60        .enumerate()61        .filter(|(n, &x)| x as i128 == law(*n as u32))62        .count();63    let shown: Vec<String> = s.iter().map(|x| x.to_string()).collect();64    println!("  blocks levels 0..15: {}", shown.join(" "));65    println!(66        "  law (8^n - 1)/7 - 3^n + n + 1 holds at {ok} of {} levels; {}",67        s.len(),68        describe(&s)69    );70    let built = blocks(3, &d.tile, 10);71    let same = (0..=10)72        .filter(|&n| built[n].partner == lemma(n as u32))73        .count();74    println!("  matching lemma equals the glued matching at {same} of 11 levels 0..10");75    let splits = (0..15)76        .filter(|&n| {77            let u = (3i128.pow(n as u32) - 2 * n as i128 - 1) / 2;78            s[n + 1] as i128 - 8 * s[n] as i128 == 10 * u + 3 * n as i12879        })80        .count();81    println!("  new loops per gluing = 10 U_n + 3n with U_n = (3^n - 2n - 1)/2 at {splits} of 15 gluings");82}