#![allow(dead_code)] use rand::distributions::{Distribution, Standard}; use rand::{Rng, SeedableRng}; use std::fmt::Debug; use std::cmp::Ordering; /// Get a random vector of `n` elements from the standard distribution pub fn random_vec(n: usize, rng: &mut R) -> Vec where Standard: Distribution, R: Rng { let mut list: Vec = Vec::with_capacity(n); for _ in 0..n { list.push(rng.gen()) } list } /// Get a random vector of `n` vectors of up to `m` elements from the standard distribution pub fn random_vec_of_vec(n: usize, m: usize, rng: &mut R) -> Vec> where Standard: Distribution, R: Rng { let mut list: Vec> = Vec::with_capacity(n); for _ in 0..n { let l = rng.gen_range(0, m + 1); list.push(random_vec(l, rng)) } list } /// Get the difference between two arrays pub fn arraydiff(left: &[T], right: &[T], max_miss: usize, disp: F) where T: Debug + PartialEq, F: Fn(&T, &T) { let mut mismatches = 0; if left.len() != right.len() { panic!("Array length mismatch: left.len() = {}, right.len() = {}", left.len(), right.len()) } for i in 0..left.len() { if left[i] != right[i] { if mismatches < max_miss { println!( "Array element mismatch: left[{}] = {:?} != right[{}] = {:?}", i, left[i], i, right[i] ); disp(&left[i], &right[i]); } mismatches += 1; } } if mismatches != 0 { panic!( "Had {} mismatches of {} elements, or {}%", mismatches, left.len() as f64, 100.0 * (mismatches as f64) / (left.len() as f64) ); } } /// Check whether a vector of `n` elements is sorted properly by `sorter` pub fn sorts_properly(n: usize, mut sorter: S) where Standard: Distribution, T: Debug + Ord + Clone, S: FnMut(&mut [T]) { let mut rng = rand_xoshiro::Xoroshiro64StarStar::from_seed([0; 8]); let mut list = random_vec(n, &mut rng); let mut sorted = list.clone(); sorted.sort_unstable(); sorter(&mut list); arraydiff(&sorted, &list, 100, |_, _| {}); } /// Check whether an array of `n` arrays of up to `n` elements is sorted properly by `sorter` pub fn array_sorts_properly(n: usize, m: usize, mut sorter: S) where Standard: Distribution, T: Debug + Ord + Clone, S: FnMut(&mut [Vec]) { let mut rng = rand_xoshiro::Xoroshiro64StarStar::from_seed([0; 8]); let mut list = random_vec_of_vec(n, m, &mut rng); let mut sorted = list.clone(); sorted.sort_unstable(); sorter(&mut list); arraydiff(&sorted, &list, 100, |_, _| {}); } pub fn sorts_properly_by(n: usize, mut sorter: S, comparator: C) where Standard: Distribution, T: Debug + PartialEq + Clone, S: FnMut(&mut [T]), C: Copy + Fn(&T, &T) -> Ordering { let mut rng = rand_xoshiro::Xoroshiro64StarStar::from_seed([0; 8]); let mut list = random_vec(n, &mut rng); let mut sorted = list.clone(); sorted.sort_by(comparator); sorter(&mut list); arraydiff(&sorted, &list, 100, |a, b| println!("Comparator: {:?}", comparator(a, b))); } pub fn partial_sorts_properly(n: usize, sorter: S) where Standard: Distribution, T: PartialOrd + Clone + Debug, S: FnMut(&mut [T]) { sorts_properly_by(n, sorter, |a, b| a.partial_cmp(b).unwrap()) }