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}