#[cfg_attr(
not(all(target_arch = "x86_64", feature = "std", feature = "threadteam")),
allow(dead_code)
)]
pub(crate) fn lower_area_split(
m: usize,
n: usize,
i: usize,
parts: usize,
align: usize,
) -> usize {
if i == 0 {
return 0;
}
if i >= parts {
return n;
}
let (m, w, p) = (m as u128, n.min(m) as u128, parts as u128);
let total = w * m - w * w.saturating_sub(1) / 2;
let big_b = 2 * m + 1;
let q = p * big_b * big_b - 8 * total * i as u128;
let fits =
|k: u128| k <= (big_b + 1) / 2 && p * (big_b + 1 - 2 * k).pow(2) >= q;
let mut k = (big_b + 1 - (q / p).isqrt()) / 2;
while fits(k + 1) {
k += 1;
}
while !fits(k) {
k -= 1;
}
(k as usize).next_multiple_of(align.max(1)).min(n)
}
#[cfg(test)]
mod tests {
use super::lower_area_split;
#[test]
fn lower_boundaries_are_the_rounded_roots() {
let cuts = |m, n, parts: usize, count: usize| -> Vec<usize> {
(1..=count)
.map(|i| lower_area_split(m, n, i, parts, 1))
.collect()
};
assert_eq!(
cuts(4096, 4096, 16, 8),
[130, 265, 404, 549, 700, 858, 1024, 1200]
);
assert_eq!(cuts(1024, 1024, 64, 8), [8, 16, 24, 33, 41, 49, 58, 66]);
assert_eq!(cuts(2047, 2048, 7, 6), [152, 317, 500, 707, 953, 1274]);
}
#[test]
fn lower_parts_cover_the_triangle_with_equal_areas() {
for &(m, n) in &[
(4096usize, 4096usize),
(2047, 2048),
(301, 301),
(40, 40),
(9, 10),
(900, 300),
] {
for align in [1usize, 8] {
for parts in [1usize, 2, 3, 4, 7, 16, 64] {
let cuts: Vec<usize> = (0..=parts)
.map(|i| lower_area_split(m, n, i, parts, align))
.collect();
assert_eq!((cuts[0], cuts[parts]), (0, n));
assert!(
cuts.windows(2).all(|w| w[0] <= w[1]),
"{m}x{n}/{parts}: {cuts:?}"
);
assert!(
cuts[1..parts]
.iter()
.all(|c| c % align == 0 || *c == n)
);
let area = |c0: usize, c1: usize| {
(c0..c1.min(m)).map(|c| m - c).sum::<usize>()
};
let total = area(0, n);
for w in cuts.windows(2) {
assert!(
area(w[0], w[1]).abs_diff(total / parts)
<= align * m,
"{m}x{n}/{parts}/{align}: {cuts:?}"
);
}
}
}
}
}
}