main
John Lauer source: the crates, flows, docs and skills of adom-aiflow 0.1.5, so PRs can be opened against them ad411ea
//! route BOARD SPEC OUT_PLAN [passes]  : the router on its own, for checking against the reference.
use aiflow_board::Board;
use aiflow_router::{drive::route_board, Router, Rules};
fn main() {
    let a: Vec<String> = std::env::args().collect();
    let board = Board::load(&a[1]).unwrap();
    let spec: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(&a[2]).unwrap()).unwrap();
    let rules = Rules::from_spec(&spec);
    let passes: usize = a.get(4).and_then(|p| p.parse().ok()).unwrap_or(1);
    let t0 = std::time::Instant::now();
    let mut r = Router::new(board, rules, true);
    let (plan, report, failed) = route_board(&mut r, passes, 8, 400);
    std::fs::write(&a[3], serde_json::to_string_pretty(&serde_json::json!({"engine": "adom-aiflow router", "nets": plan})).unwrap()).unwrap();
    std::fs::write(format!("{}.report.json", a[3]), serde_json::to_string_pretty(&report).unwrap()).unwrap();
    eprintln!("done: {failed} failed, {} entries, {:.1}s", plan.len(), t0.elapsed().as_secs_f64());
}