design.rs

5.7 kB · rust · 206 lines

1use mrlycore::Tensor;2use mrlymath::bang::baseq::axis_maps;3use mrlymath::bang::factory::{corners_to_code, residue_corners};4use mrlymath::bang::universe::permutations;5use mrlynum::graph::core_graph;6use std::collections::BTreeSet;78pub const BASE: usize = 3;910pub fn plane(code: u128, base: usize, level: usize) -> Tensor {11    mrlymath::two::create(code, base, level, 0, base)12        .expect("a plane design renders")13        .types()14        .clone()15}1617pub fn sponge_code() -> u128 {18    let filled: Vec<Vec<u8>> = residue_corners(3, BASE)19        .into_iter()20        .filter(|corner| corner.iter().filter(|digit| **digit == 1).count() <= 1)21        .collect();22    corners_to_code(&filled, 3, BASE)23}2425pub fn sponge(level: usize) -> Tensor {26    mrlymath::three::create(sponge_code(), BASE, level, BASE)27        .expect("the sponge renders")28        .types()29        .clone()30}3132pub fn filled(grid: &Tensor) -> Vec<usize> {33    grid.bytes()34        .iter()35        .enumerate()36        .filter(|(_, cell)| **cell != 0)37        .map(|(flat, _)| flat)38        .collect()39}4041pub fn strides(shape: &[usize]) -> Vec<usize> {42    let mut out = vec![1; shape.len()];43    for axis in (0..shape.len().saturating_sub(1)).rev() {44        out[axis] = out[axis + 1] * shape[axis + 1];45    }46    out47}4849pub fn coords(flat: usize, shape: &[usize]) -> Vec<usize> {50    let mut left = flat;51    strides(shape)52        .iter()53        .map(|stride| {54            let index = left / stride;55            left %= stride;56            index57        })58        .collect()59}6061pub struct Graph {62    pub shape: Vec<usize>,63    pub cells: Vec<usize>,64    pub adjacency: Vec<Vec<u32>>,65}6667impl Graph {68    pub fn of(grid: &Tensor) -> Graph {69        let network = core_graph(grid).expect("a grid has a core graph");70        let mut adjacency: Vec<Vec<u32>> = vec![Vec::new(); network.nodes.len()];71        for branch in &network.branches {72            adjacency[branch.parent].push(branch.child as u32);73            adjacency[branch.child].push(branch.parent as u32);74        }75        for row in adjacency.iter_mut() {76            row.sort_unstable();77        }78        Graph {79            shape: grid.shape.clone(),80            cells: filled(grid),81            adjacency,82        }83    }8485    pub fn nodes(&self) -> usize {86        self.adjacency.len()87    }8889    pub fn labels(&self) -> Vec<usize> {90        let mut parent: Vec<usize> = (0..self.nodes()).collect();91        for (node, row) in self.adjacency.iter().enumerate() {92            for other in row {93                let (a, b) = (root(&mut parent, node), root(&mut parent, *other as usize));94                if a != b {95                    parent[a] = b;96                }97            }98        }99        (0..self.nodes())100            .map(|node| root(&mut parent, node))101            .collect()102    }103}104105fn root(parent: &mut [usize], mut node: usize) -> usize {106    while parent[node] != node {107        parent[node] = parent[parent[node]];108        node = parent[node];109    }110    node111}112113pub struct Components {114    pub count: usize,115    pub giant: Tensor,116    pub share: f64,117    pub spanning: bool,118}119120pub fn components(grid: &Tensor) -> Components {121    let graph = Graph::of(grid);122    let labels = graph.labels();123    let mut sizes = vec![0usize; graph.nodes()];124    for label in &labels {125        sizes[*label] += 1;126    }127    let count = sizes.iter().filter(|size| **size > 0).count();128    let best = (0..graph.nodes())129        .max_by_key(|node| (sizes[*node], usize::MAX - node))130        .unwrap_or(0);131    let mut bytes = vec![0u8; grid.size()];132    let mut low = vec![usize::MAX; grid.shape.len()];133    let mut high = vec![0usize; grid.shape.len()];134    for (node, flat) in graph.cells.iter().enumerate() {135        if labels[node] == best {136            bytes[*flat] = 1;137            for (axis, at) in coords(*flat, &grid.shape).iter().enumerate() {138                low[axis] = low[axis].min(*at);139                high[axis] = high[axis].max(*at);140            }141        }142    }143    let walls =144        (0..grid.shape.len()).all(|axis| low[axis] == 0 && high[axis] + 1 == grid.shape[axis]);145    let held = if graph.nodes() == 0 { 0 } else { sizes[best] };146    Components {147        count,148        giant: Tensor::of(bytes, grid.shape.clone()),149        share: if graph.nodes() == 0 {150            0.0151        } else {152            held as f64 / graph.nodes() as f64153        },154        spanning: walls,155    }156}157158pub fn group() -> Vec<Vec<usize>> {159    let cells = residue_corners(2, BASE);160    let maps = axis_maps(BASE);161    let mut out = Vec::new();162    for order in permutations(2) {163        for first in &maps {164            for second in &maps {165                out.push(166                    cells167                        .iter()168                        .map(|cell| {169                            first[cell[order[0]] as usize] * BASE + second[cell[order[1]] as usize]170                        })171                        .collect(),172                );173            }174        }175    }176    out177}178179pub fn carry(element: &[usize], code: u128) -> u128 {180    element181        .iter()182        .enumerate()183        .filter(|(index, _)| code >> index & 1 == 1)184        .map(|(_, image)| 1u128 << image)185        .sum()186}187188pub fn orbit(group: &[Vec<usize>], code: u128) -> BTreeSet<u128> {189    group.iter().map(|element| carry(element, code)).collect()190}191192pub fn classes(group: &[Vec<usize>]) -> Vec<(u128, usize)> {193    let mut seen = vec![false; 512];194    let mut out = Vec::new();195    for code in 0..512u128 {196        if seen[code as usize] {197            continue;198        }199        let members = orbit(group, code);200        out.push((code, members.len()));201        for member in members {202            seen[member as usize] = true;203        }204    }205    out206}