research-stack.rs

2.1 kB · rust · 77 lines

1use mrlycore::errors::Result;2use mrlyfig::board::Board;3use mrlyfig::ink::Ramp;4use mrlyfig::{ink, save};5use mrlynum::gauss::{classes, Ring};6use std::collections::HashSet;78const RING: Ring = Ring::Gaussian;9const BOUND: u64 = 60;1011fn nodes(bound: u64) -> Vec<(f64, f64, usize)> {12    let mut seen = HashSet::new();13    let mut out = Vec::new();14    for den in classes(RING, bound) {15        let n = RING.norm(den.0, den.1) as i64;16        let lit = classes(RING, bound / n as u64).len();17        for p in 0..n {18            for q in 0..n {19                let g = RING.gcd((p, q), den);20                if RING.norm(g.0, g.1) != 1 {21                    continue;22                }23                let x = (p * den.0 + q * den.1).rem_euclid(n);24                let y = (q * den.0 - p * den.1).rem_euclid(n);25                if !seen.insert((x, y, n)) {26                    continue;27                }28                out.push((x as f64 / n as f64, y as f64 / n as f64, lit));29            }30        }31    }32    out33}3435fn wrapped(stack: Vec<(f64, f64, usize)>) -> Vec<(f64, f64, usize)> {36    let mut out = Vec::new();37    for (x, y, lit) in stack {38        out.push((x, y, lit));39        if x == 0.0 {40            out.push((1.0, y, lit));41        }42        if y == 0.0 {43            out.push((x, 1.0, lit));44        }45        if x == 0.0 && y == 0.0 {46            out.push((1.0, 1.0, lit));47        }48    }49    out50}5152fn main() -> Result<()> {53    assert_eq!(nodes(50).len(), 672);54    let mut stack = nodes(BOUND);55    assert_eq!(stack.len(), 880);56    let top = classes(RING, BOUND).len();57    assert_eq!(top, 46);58    stack = wrapped(stack);59    assert_eq!(stack.len(), 917);60    stack.sort_by_key(|node| node.2);6162    let ramp = Ramp::new(vec![ink::ground(), ink::blue(), ink::yellow()]);63    let mut board = Board::square();64    let frame = board.frame(0.08);65    for (x, y, lit) in stack {66        let share = lit as f64 / top as f64;67        let (px, py) = frame.at(x, 1.0 - y);68        board.disc(69            px,70            py,71            3.5 + 15.0 * share.powf(0.7),72            ramp.at(share.powf(0.30)),73        );74    }75    save("research-stack", &board)?;76    Ok(())77}