use crate::{math::ks_test, result::TestResult, rng::Rng};
const ATTEMPTS: usize = 12_000;
const MEAN: f64 = 3_523.0;
const SIGMA: f64 = 21.9;
pub fn parking_lot(rng: &mut impl Rng, quick: bool) -> TestResult {
let repeats = if quick { 5 } else { 10 };
let mut p_values = Vec::with_capacity(repeats);
for _ in 0..repeats {
let parked = simulate(rng);
let z = (parked as f64 - MEAN) / SIGMA;
let p = crate::math::normal_cdf(z);
p_values.push(p.clamp(1e-15, 1.0 - 1e-15));
}
let p_value = ks_test(&mut p_values);
TestResult::with_note(
"diehard::parking_lot",
p_value,
format!("attempts={ATTEMPTS}, mean={MEAN}, σ={SIGMA}, repeats={repeats}"),
)
}
fn simulate(rng: &mut impl Rng) -> usize {
let mut cars: Vec<(f64, f64)> = Vec::with_capacity(ATTEMPTS / 3);
let mut parked = 0usize;
for _ in 0..ATTEMPTS {
let x = rng.next_f64() * 100.0;
let y = rng.next_f64() * 100.0;
let fits = cars
.iter()
.all(|&(cx, cy)| (cx - x).abs() >= 1.0 || (cy - y).abs() >= 1.0);
if fits {
cars.push((x, y));
parked += 1;
}
}
parked
}