main.rs
2.7 kB · rust · 85 lines
1mod census;2mod design;3mod terms;45use design::Design;67fn run_terms(design: &Design, top: u32, threads: usize) {8 let stored = terms::stored(design);9 let delta = design.density();10 println!(11 "{} k {} delta {:.6} live domain n <= {}",12 design.name, design.fill, delta, top13 );14 let mut last_gap = 0.0;15 let mut agree = true;16 for term in terms::terms(design, top, threads) {17 let ratio = term.value as f64 / (design.fill as f64).powi(term.level as i32);18 let gap = ratio - delta;19 let kept = stored20 .iter()21 .find(|(n, _)| *n == term.level)22 .map(|(_, v)| *v);23 let tag = match kept {24 Some(v) if v == term.value => "stored",25 Some(_) => "DIFFERS",26 None => "fresh",27 };28 agree &= tag != "DIFFERS";29 println!(30 "n {:2} A {:>26} A/k^n {:.6} gap {:+.2e} halving {:.2} {:.1}s {}",31 term.level,32 term.value,33 ratio,34 gap,35 if last_gap != 0.0 { gap / last_gap } else { 0.0 },36 term.seconds,37 tag38 );39 last_gap = gap;40 }41 for (n, v) in stored.iter().filter(|(n, _)| *n > top) {42 let gap = *v as f64 / (design.fill as f64).powi(*n as i32) - delta;43 println!("n {:2} A {:>26} gap {:+.2e} stored only", n, v, gap);44 }45 let brute_top = match design.dimension {46 3 => 5,47 _ => 8,48 };49 let brute: Vec<u64> = (1..=brute_top).map(|n| terms::brute(design, n)).collect();50 let matches = brute.iter().enumerate().all(|(i, b)| {51 stored52 .iter()53 .any(|(n, v)| *n as usize == i + 1 && *v == *b as i128)54 });55 println!(56 "{} live terms agree with stored {}, brute force to n = {} agrees {}",57 design.name, agree, brute_top, matches58 );59}6061fn main() {62 let args: Vec<String> = std::env::args().skip(1).collect();63 let threads = std::thread::available_parallelism()64 .map(|n| n.get())65 .unwrap_or(8);66 match args.first().map(String::as_str) {67 Some("terms") => {68 let design = Design::named(&args[1]).expect("carpet, menger or vicsek");69 run_terms(design, args[2].parse().expect("top level"), threads);70 }71 Some("census") => {72 for level in args[1..].iter().map(|a| a.parse().expect("level")) {73 census::report(level, level == 13);74 }75 }76 _ => {77 run_terms(&design::CARPET, 18, threads);78 run_terms(&design::MENGER, 16, threads);79 run_terms(&design::VICSEK, 18, threads);80 for level in 13..=16 {81 census::report(level, level == 13);82 }83 }84 }85}