wiki-cantor-set.rs
1.5 kB · rust · 49 lines
1use figures::{ink, save, Board};2use mrlyrs::core::error::Result;34const STAGES: usize = 6;5const KEPT: usize = 63;6const CUT: usize = 31;78fn main() -> Result<()> {9 let mut board = Board::square();10 let frame = board.frame(0.08);11 let bar = frame.h / (STAGES as f64 + (STAGES - 1) as f64 * 0.9);12 let pitch = bar * 1.9;13 let mut kept = 0usize;14 let mut cut = 0usize;15 for stage in 0..STAGES {16 let y = frame.y + stage as f64 * pitch;17 let side = 3f64.powi(-(stage as i32));18 let row = lefts(stage);19 assert_eq!(row.len(), 1 << stage);20 let length: f64 = row.len() as f64 * side;21 assert!((length - (2.0f64 / 3.0).powi(stage as i32)).abs() < 1e-12);22 if stage > 0 {23 for &a in &lefts(stage - 1) {24 let x = frame.x + frame.w * (a + side);25 board.rect(x, y, frame.w * side, bar, ink::dim());26 cut += 1;27 }28 }29 for &a in &row {30 board.rect(frame.x + frame.w * a, y, frame.w * side, bar, ink::blue());31 kept += 1;32 }33 }34 assert_eq!(kept, KEPT);35 assert_eq!(cut, CUT);36 save("wiki-cantor-set", &board)?;37 Ok(())38}3940fn lefts(stage: usize) -> Vec<f64> {41 (0..1usize << stage)42 .map(|i| {43 (0..stage)44 .filter(|&l| (i >> (stage - 1 - l)) & 1 == 1)45 .map(|l| 2.0 * 3f64.powi(-(l as i32 + 1)))46 .sum()47 })48 .collect()49}