use crate::{math::igamc, result::TestResult};
pub fn block_frequency(bits: &[u8], m: usize) -> TestResult {
let n = bits.len();
if n < 100 || m < 20 || m > n {
return TestResult::insufficient("nist::block_frequency", "n < 100 or m out of range");
}
let num_blocks = n / m;
let chi_sq: f64 = bits
.chunks_exact(m)
.take(num_blocks)
.map(|block| {
let ones: f64 = block.iter().map(|&b| b as f64).sum();
let pi_j = ones / m as f64;
(pi_j - 0.5) * (pi_j - 0.5)
})
.sum::<f64>()
* 4.0
* m as f64;
let p_value = igamc(num_blocks as f64 / 2.0, chi_sq / 2.0);
TestResult::with_note(
"nist::block_frequency",
p_value,
format!("n={n}, M={m}, N={num_blocks}, χ²={chi_sq:.4}"),
)
}