const STOP: [usize; 5] = [128, 8, 64, 192, 4];
const TRIM: [usize; 5] = [256, 3, 32, 768, 3];
fn trim(
ids: &mut Vec<usize>,
[max_block, copies, min_tokens, max_tokens, min_copies]: [usize; 5],
) -> bool {
let n = ids.len();
let looped = (1..=max_block).find(|&block| {
let span = (copies * block).clamp(min_tokens, max_tokens);
let span = block * min_copies.max(span.div_ceil(block));
span <= n && (n - span + block..n).all(|i| ids[i] == ids[i - block])
});
let Some(block) = looped else { return false };
while ids.len() >= 2 * block
&& ids[ids.len() - block..] == ids[ids.len() - 2 * block..ids.len() - block]
{
ids.truncate(ids.len() - block);
}
true
}
pub fn stop(ids: &mut Vec<usize>) -> bool {
trim(ids, STOP)
}
pub fn trim_at_budget(ids: &mut Vec<usize>) {
trim(ids, TRIM);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn loops_stop_and_repeats_stay() {
let mut ids = vec![5; 63];
assert!(!stop(&mut ids));
ids.push(5);
assert!(stop(&mut ids));
assert_eq!(ids, [5]);
let block: Vec<usize> = (10..18).collect();
let mut ids = [vec![1, 2], block.repeat(7)].concat();
assert!(!stop(&mut ids));
ids.extend(&block);
assert!(stop(&mut ids));
assert_eq!(ids, [vec![1, 2], block.clone()].concat());
let block: Vec<usize> = (100..148).collect();
let mut ids = block.repeat(3);
assert!(!stop(&mut ids));
ids.extend(&block);
assert!(stop(&mut ids));
assert_eq!(ids, block);
let block: Vec<usize> = (20..31).collect();
let mut ids = [vec![1], block.repeat(3)].concat();
trim_at_budget(&mut ids);
assert_eq!(ids, [vec![1], block].concat());
let mut ids = (20..30).collect::<Vec<_>>().repeat(3);
trim_at_budget(&mut ids);
assert_eq!(ids.len(), 30);
}
}