use super::{super::*, *};
#[yare::parameterized(
one_to_ten = { input_1_to_10 },
one = { input_1 },
empty = { input_empty },
)]
fn new_bisector(input: fn() -> Vec<u32>) {
let values = input();
let bisect = Bisector::new(&values);
assert_eq!(values.len(), bisect.view().len());
}
#[test]
fn bisect_on_empty_view_converge_to_left() {
let values = input_empty();
let bisector = Bisector::new(&values);
let start_from = Indices::new(0, 0);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), start_from);
assert_eq!(step.indices, start_from);
assert!(step.result.is_none())
}
#[test]
fn bisect_on_empty_view_converge_to_right() {
let values = input_empty();
let bisector = Bisector::new(&values);
let start_from = Indices::new(0, 0);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Right(value), start_from);
assert_eq!(step.indices, start_from);
assert!(step.result.is_none())
}
#[test]
fn bisect_on_view_with_one_element_converge_to_left() {
let values = input_1();
let bisector = Bisector::new(&values);
let start_from = Indices::from_bisector(&bisector);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), start_from);
assert_eq!(step.indices, Indices::new(0, 0));
assert_eq!(step.result.unwrap().unwrap_converge_left(), 1);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), step.indices);
assert_eq!(step.indices, Indices::new(0, 0));
assert!(step.result.is_none());
}
#[test]
fn bisect_on_view_with_one_element_converge_to_right() {
let values = input_1();
let bisector = Bisector::new(&values);
let start_from = Indices::from_bisector(&bisector);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Right(value), start_from);
assert_eq!(step.indices, Indices::new(1, 1));
assert_eq!(step.result.unwrap().unwrap_converge_right(), 1);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Right(value), step.indices);
assert_eq!(step.indices, Indices::new(1, 1));
assert!(step.result.is_none());
}
#[test]
fn bisect_on_view_with_many_elements_converge_to_left() {
let values = input_1_to_10();
let bisector = Bisector::new(&values);
let start_from = Indices::from_bisector(&bisector);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), start_from);
assert_eq!(step.indices, Indices::new(0, 5));
assert_eq!(step.result.unwrap().unwrap_converge_left(), 6);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), step.indices);
assert_eq!(step.indices, Indices::new(0, 2));
assert_eq!(step.result.unwrap().unwrap_converge_left(), 3);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), step.indices);
assert_eq!(step.indices, Indices::new(0, 1));
assert_eq!(step.result.unwrap().unwrap_converge_left(), 2);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), step.indices);
assert_eq!(step.indices, Indices::new(0, 0));
assert_eq!(step.result.unwrap().unwrap_converge_left(), 1);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), step.indices);
assert_eq!(step.indices, Indices::new(0, 0));
assert!(step.result.is_none());
}
#[test]
fn bisect_on_view_with_many_elements_converge_to_right() {
let values = input_1_to_10();
let bisector = Bisector::new(&values);
let start_from = Indices::from_bisector(&bisector);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Right(value), start_from);
assert_eq!(step.indices, Indices::new(6, 10));
assert_eq!(step.result.unwrap().unwrap_converge_right(), 6);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Right(value), step.indices);
assert_eq!(step.indices, Indices::new(9, 10));
assert_eq!(step.result.unwrap().unwrap_converge_right(), 9);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Right(value), step.indices);
assert_eq!(step.indices, Indices::new(10, 10));
assert_eq!(step.result.unwrap().unwrap_converge_right(), 10);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Right(value), step.indices);
assert_eq!(step.indices, Indices::new(10, 10));
assert!(step.result.is_none());
}
#[test]
fn bisect_on_view_with_many_elements_converge_zig_zag() {
let values = input_1_to_10();
let bisector = Bisector::new(&values);
let start_from = Indices::from_bisector(&bisector);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), start_from);
assert_eq!(step.indices, Indices::new(0, 5));
assert_eq!(step.result.unwrap().unwrap_converge_left(), 6);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Right(value), step.indices);
assert_eq!(step.indices, Indices::new(3, 5));
assert_eq!(step.result.unwrap().unwrap_converge_right(), 3);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), step.indices);
assert_eq!(step.indices, Indices::new(3, 4));
assert_eq!(step.result.unwrap().unwrap_converge_left(), 5);
let final_step: Step<u32, u32> =
bisector.bisect(|&value| ConvergeTo::Left(value), step.indices);
assert_eq!(final_step.indices, Indices::new(3, 3));
assert_eq!(final_step.result.unwrap().unwrap_converge_left(), 4);
let step: Step<u32, u32> =
bisector.bisect(|&value| ConvergeTo::Left(value), final_step.indices);
assert_eq!(step.indices, Indices::new(3, 3));
assert!(step.result.is_none());
let step: Step<u32, u32> =
bisector.bisect(|&value| ConvergeTo::Right(value), final_step.indices);
assert_eq!(step.indices, Indices::new(3, 3));
assert!(step.result.is_none());
}
#[test]
fn bisect_on_view_with_many_elements_re_use_same_indices_means_no_progress() {
let values = input_1_to_10();
let bisector = Bisector::new(&values);
let start_from = Indices::from_bisector(&bisector);
let expected_next_indices = Indices::new(0, 5);
let expected_output_value = 6;
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), start_from);
assert_eq!(step.indices, expected_next_indices);
assert_eq!(
step.result.unwrap().unwrap_converge_left(),
expected_output_value
);
let step: Step<u32, u32> = bisector.bisect(|&value| ConvergeTo::Left(value), start_from);
assert_eq!(step.indices, expected_next_indices);
assert_eq!(
step.result.unwrap().unwrap_converge_left(),
expected_output_value
);
}