use pathfinding::directed::cycle_detection::*;
#[test]
fn floyd_works() {
assert_eq!(floyd(-10, |x| (x + 5) % 6 + 3), (3, 6, 2));
}
#[test]
fn brent_works() {
assert_eq!(brent(-10, |x| (x + 5) % 6 + 3), (3, 6, 2));
}
#[test]
fn floyd_partial_works() {
let (lam, elem, mu_tilde) = floyd_partial(-10, |x| (x + 5) % 6 + 3);
assert_eq!(lam, 3);
assert!([4, 6, 8].contains(&elem));
assert!(2 <= mu_tilde);
assert!(mu_tilde < 2 + 3);
}
#[test]
fn brent_partial_works() {
let (lam, elem, mu_tilde) = brent_partial(-10, |x| (x + 5) % 6 + 3);
assert_eq!(lam, 3);
assert!([4, 6, 8].contains(&elem));
assert!(2 <= mu_tilde);
}
#[test]
fn partial_functions_match_full_functions() {
let f = |x| (x + 5) % 6 + 3;
let (lam_floyd, elem_floyd, mu_floyd) = floyd(-10, f);
let (lam_floyd_partial, elem_floyd_partial, mu_tilde_floyd) = floyd_partial(-10, f);
let (lam_brent, elem_brent, mu_brent) = brent(-10, f);
let (lam_brent_partial, elem_brent_partial, mu_tilde_brent) = brent_partial(-10, f);
assert_eq!(lam_floyd, lam_floyd_partial);
assert_eq!(lam_brent, lam_brent_partial);
assert_eq!(lam_floyd, lam_brent);
assert!([4, 6, 8].contains(&elem_floyd));
assert!([4, 6, 8].contains(&elem_floyd_partial));
assert!([4, 6, 8].contains(&elem_brent));
assert!([4, 6, 8].contains(&elem_brent_partial));
assert_eq!(mu_floyd, mu_brent);
assert!(mu_floyd <= mu_tilde_floyd);
assert!(mu_tilde_floyd < mu_floyd + lam_floyd);
assert!(mu_brent <= mu_tilde_brent);
}
#[test]
fn test_longer_cycle() {
let f = |x: i32| (x + 1) % 100;
let (lam_floyd, elem_floyd, mu_floyd) = floyd(0, f);
let (lam_floyd_partial, elem_floyd_partial, mu_tilde_floyd) = floyd_partial(0, f);
let (lam_brent, elem_brent, mu_brent) = brent(0, f);
let (lam_brent_partial, elem_brent_partial, mu_tilde_brent) = brent_partial(0, f);
assert_eq!(lam_floyd, 100);
assert_eq!(lam_floyd_partial, 100);
assert_eq!(lam_brent, 100);
assert_eq!(lam_brent_partial, 100);
assert_eq!(mu_floyd, 0);
assert_eq!(mu_brent, 0);
assert!((0..100).contains(&elem_floyd));
assert!((0..100).contains(&elem_floyd_partial));
assert!((0..100).contains(&elem_brent));
assert!((0..100).contains(&elem_brent_partial));
assert!(mu_floyd <= mu_tilde_floyd);
assert!(mu_tilde_floyd < mu_floyd + lam_floyd);
assert!(mu_brent <= mu_tilde_brent);
}
#[test]
fn test_short_cycle_large_mu() {
let f = |x: i32| if x == 10 { 0 } else { x + 1 };
let (lam_floyd, elem_floyd, mu_floyd) = floyd(-100, f);
let (lam_floyd_partial, elem_floyd_partial, mu_tilde_floyd) = floyd_partial(-100, f);
let (lam_brent, elem_brent, mu_brent) = brent(-100, f);
let (lam_brent_partial, elem_brent_partial, mu_tilde_brent) = brent_partial(-100, f);
assert_eq!(lam_floyd, 11);
assert_eq!(lam_floyd_partial, 11);
assert_eq!(lam_brent, 11);
assert_eq!(lam_brent_partial, 11);
assert_eq!(mu_floyd, 100);
assert_eq!(mu_brent, 100);
assert!((0..=10).contains(&elem_floyd));
assert!((0..=10).contains(&elem_floyd_partial));
assert!((0..=10).contains(&elem_brent));
assert!((0..=10).contains(&elem_brent_partial));
assert!(mu_floyd <= mu_tilde_floyd);
assert!(mu_tilde_floyd < mu_floyd + lam_floyd);
assert!(mu_brent <= mu_tilde_brent);
}