design.rs
1.5 kB · rust · 68 lines
1use mrlynum::series::APERY;2use std::f64::consts::PI;34pub struct Design {5 pub name: &'static str,6 pub dimension: usize,7 pub invert: bool,8 pub fill: u64,9}1011pub const CARPET: Design = Design {12 name: "carpet",13 dimension: 2,14 invert: false,15 fill: 8,16};17pub const MENGER: Design = Design {18 name: "menger",19 dimension: 3,20 invert: false,21 fill: 20,22};23pub const VICSEK: Design = Design {24 name: "vicsek",25 dimension: 2,26 invert: true,27 fill: 5,28};2930impl Design {31 pub fn named(name: &str) -> Option<&'static Design> {32 [&CARPET, &MENGER, &VICSEK]33 .into_iter()34 .find(|d| d.name == name)35 }3637 pub fn origin_filled(&self) -> bool {38 !self.invert39 }4041 pub fn density(&self) -> f64 {42 match self.name {43 "carpet" => 189.0 / (32.0 * PI * PI),44 "menger" => (513.0 / 520.0) / APERY,45 _ => 27.0 / (4.0 * PI * PI),46 }47 }4849 pub fn filled(&self, digits: &[u64]) -> bool {50 digits.iter().filter(|&&d| (d == 1) != self.invert).count() <= 151 }5253 pub fn corners(&self) -> Vec<Vec<u64>> {54 let mut out = Vec::new();55 for code in 0..3u64.pow(self.dimension as u32) {56 let mut rest = code;57 let mut digits = Vec::with_capacity(self.dimension);58 for _ in 0..self.dimension {59 digits.push(rest % 3);60 rest /= 3;61 }62 if self.filled(&digits) {63 out.push(digits);64 }65 }66 out67 }68}