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}