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}