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}