main.rs
3.3 kB · rust · 103 lines
1use mrlycore::tensor::Tensor;2use mrlymath::bang::factory::create;3use mrlymath::shape::{census, crop, named, Frac, Shape};45// DESIGNS67fn design(dimension: usize, level: usize) -> Tensor {8 if level == 0 {9 return Tensor::full(vec![1; dimension], 1);10 }11 match dimension {12 2 => create(7, 3, 2, 2, level).unwrap(),13 _ => create(23, 3, 3, 2, level).unwrap(),14 }15}1617// EXPOSURE1819fn exposed(types: &Tensor) -> usize {20 let dims = types.shape.clone();21 let rank = dims.len();22 let mut index = vec![0usize; rank];23 let mut probe = vec![0usize; rank];24 let mut count = 0;25 for flat in 0..types.size() {26 let mut rem = flat;27 for axis in (0..rank).rev() {28 index[axis] = rem % dims[axis];29 rem /= dims[axis];30 }31 if types.bytes()[flat] == 0 {32 continue;33 }34 for axis in 0..rank {35 for step in [-1i64, 1] {36 let next = index[axis] as i64 + step;37 if next < 0 || next as usize >= dims[axis] {38 count += 1;39 continue;40 }41 probe.copy_from_slice(&index);42 probe[axis] = next as usize;43 if types.get(&probe) == 0 {44 count += 1;45 }46 }47 }48 }49 count50}5152// LINES5354fn line(label: &str, name: &str, dimension: usize, radius: Frac, types: &Tensor) {55 let shape = named(name, dimension, radius).unwrap();56 let tally = census(&shape, types);57 let kept = crop(types, &shape, true);58 let inner = crop(types, &shape, false);59 let anti_kept = crop(types, &Shape::Anti(Box::new(shape.clone())), true);60 let anti_inner = crop(types, &Shape::Anti(Box::new(shape)), false);61 let filled = types.sum();62 assert_eq!(tally.filled.iter().sum::<usize>() as u64, filled);63 assert_eq!(kept.sum() as usize, tally.filled[1] + tally.filled[2]);64 assert_eq!(inner.sum() as usize, tally.filled[2]);65 assert_eq!(anti_kept.sum() as usize, tally.filled[0] + tally.filled[1]);66 assert_eq!(anti_inner.sum() as usize, tally.filled[0]);67 assert_eq!(inner.sum() + anti_kept.sum(), filled);68 assert_eq!(kept.sum() + anti_inner.sum(), filled);69 println!(70 "crop-counts {label} {name} r={}/{} filled_in={} filled_cut={} exposed_after={}",71 radius.num,72 radius.den,73 tally.filled[2],74 tally.filled[1],75 exposed(&kept)76 );77}7879fn main() {80 println!("crop-counts generator: CARGO_BUILD_JOBS=4 cargo run --release -p crop-counts");81 let half = Frac::new(1, 2);82 for level in 0..=5usize {83 let carpet = design(2, level);84 for name in ["ball", "diamond"] {85 line(&format!("levels carpet L={level}"), name, 2, half, &carpet);86 }87 }88 for level in 0..=4usize {89 let sponge = design(3, level);90 for name in ["ball", "diamond"] {91 line(&format!("levels sponge L={level}"), name, 3, half, &sponge);92 }93 }94 let carpet = design(2, 4);95 let sponge = design(3, 3);96 for rnum in 1..=24i64 {97 let radius = Frac::new(rnum, 24);98 for name in ["ball", "diamond"] {99 line("sweep carpet L=4", name, 2, radius, &carpet);100 line("sweep sponge L=3", name, 3, radius, &sponge);101 }102 }103}