use std::cmp::PartialEq;
#[test]
fn cycle_tests() {
assert_eq!(brent_cycle(&[1, 2, 4, 5, 6, 5, 4, 3, 1]), vec![1]);
assert_eq!(brent_cycle(&[1, 2, 4, 5, 6, 5, 4, 3, 2, 1]), vec![1]);
assert_eq!(brent_cycle(&[1, 2, 4, 5, 6, 5, 4, 3, 1, 2]), vec![1, 2]);
assert_eq!(brent_cycle(&[1, 2]), vec![1, 2]);
assert_eq!(brent_cycle(&[1, 1]), vec![1]);
let expectd = vec![1, 2, 4, 3];
let rtn = brent_cycle(&expectd);
assert_eq!(rtn, expectd);
let rtn = brent_cycle(&[1, 2, 4, 3, 5, 6, 7, 7, 6, 5, 3]);
assert_eq!(rtn, expectd);
}
pub fn brent_cycle<T: PartialEq + Clone>(mcyc: &[T]) -> Vec<T> {
let mut lambda: usize = 1;
let mut power: usize = 1;
let mut tortoise: &T;
let mut hare: &T;
if mcyc.len() < 2 {
return mcyc.to_vec();
}
tortoise = &mcyc[0]; hare = &mcyc[1];
let mut it: usize = 2;
while tortoise != hare {
if power == lambda {
tortoise = hare;
power *= 2;
lambda = 0;
}
hare = &mcyc[it % mcyc.len()];
lambda += 1;
it += 1;
}
if lambda == mcyc.len() {
return mcyc.to_vec();
}
tortoise = &mcyc[0];
hare = &mcyc[lambda];
it = 1; while tortoise != hare {
tortoise = &mcyc[it];
hare = &mcyc[(lambda + it) % mcyc.len()];
it += 1;
}
if it == mcyc.len() {
mcyc[0..1].to_vec()
} else {
let mut new_vec = Vec::from(&mcyc[0..it]);
let mut second_part = Vec::from(&mcyc[it + lambda..mcyc.len()]);
new_vec.append(&mut second_part);
brent_cycle(&new_vec.to_vec())
}
}