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}