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}