snail.rs
2.1 kB · rust · 55 lines
1use crate::Fault;2use mrlyrs::core::json;3use mrlyrs::num::spiral::{self, Growth, Snail};4use wasm_bindgen::prelude::*;56const TOP: u32 = 2000;7const BASE: u32 = 8;89fn read(base: u32, top: u32, growth: &str) -> Result<Snail, Fault> {10 let growth = growth.parse::<Growth>()?;11 if !(2..=BASE).contains(&base) {12 return Err(Fault::new(format!("the base is 2 to {BASE}.")));13 }14 if top == 0 || top > TOP {15 return Err(Fault::new(format!("the top is 1 to {TOP}.")));16 }17 Ok(spiral::snail(u64::from(base), u64::from(top), growth))18}1920/// Packs the snail of the whole numbers to the top: five numbers a tile, the x and y of its lower-left corner, its side, its level and one when the number is prime, in the order one, two, three and on.21#[wasm_bindgen]22pub fn snail_cells(base: u32, top: u32, growth: &str) -> Result<Vec<i32>, Fault> {23 let shell = read(base, top, growth)?;24 let mut out = Vec::with_capacity(5 * shell.tiles.len());25 for tile in &shell.tiles {26 out.push(tile.x as i32);27 out.push(tile.y as i32);28 out.push(tile.side as i32);29 out.push(tile.level as i32);30 out.push(i32::from(tile.prime));31 }32 Ok(out)33}3435/// Reads the snail: the count of tiles, the primes at or below the top, the tiles grown past a unit cell, the tally at each level, the largest side, the drawn area and the box the tiles fill, as JSON.36#[wasm_bindgen]37pub fn snail_read(base: u32, top: u32, growth: &str) -> Result<String, Fault> {38 let shell = read(base, top, growth)?;39 let grown = shell.tiles.iter().filter(|tile| tile.level > 0).count();40 let side = shell.tiles.iter().map(|tile| tile.side).max().unwrap_or(1);41 Ok(json!({42 "tiles": shell.tiles.len(),43 "primes": shell.primes,44 "grown": grown,45 "levels": shell.levels,46 "peak": shell.levels.len() - 1,47 "side": side,48 "area": shell.area as u64,49 "low": [shell.low.0, shell.low.1],50 "high": [shell.high.0, shell.high.1],51 "width": shell.high.0 - shell.low.0,52 "height": shell.high.1 - shell.low.1,53 })54 .to_string())55}