use std::cmp::Ordering;
pub fn build_orderings<T>(sorted_dists: &Vec<Vec<(usize, T)>>, combination_fn: &dyn Fn(&[T]) -> Option<T>) -> Vec<Vec<usize>>
where
T: Copy + PartialOrd + num_traits::Bounded + num_traits::Zero + core::ops::Sub<Output=T>,
{
let factor_count = sorted_dists.len();
let mut orderings: Vec<Vec<usize>> = Vec::with_capacity(3);
orderings.push({
let mut ordering = Vec::with_capacity(factor_count);
for i in 0..factor_count {
let mut factors: Vec<T> = sorted_dists.iter().map(|inner_dist| inner_dist[0].1).collect();
let comb_val_0 = combination_fn(&factors).unwrap_or(T::zero());
factors[i] = sorted_dists[i][1].1;
let comb_val_1 = combination_fn(&factors).unwrap_or(T::zero());
ordering.push((comb_val_0 - comb_val_1, i));
}
ordering.sort_by(|(val_a, _idx_a), (val_b, _idx_b)| val_a.partial_cmp(&val_b).unwrap_or(Ordering::Equal));
let ordering = ordering.into_iter().map(|(_val, idx)| idx).collect();
ordering
});
orderings.push({
let mut ordering = Vec::with_capacity(factor_count);
for i in 0..factor_count {
let mut factors: Vec<T> = sorted_dists.iter().map(|inner_dist| inner_dist[0].1).collect();
factors[i] = sorted_dists[i][1].1;
let comb_val = combination_fn(&factors).unwrap_or(T::zero());
ordering.push((comb_val, i));
}
ordering.sort_by(|(val_a, _idx_a), (val_b, _idx_b)| val_b.partial_cmp(&val_a).unwrap_or(Ordering::Equal));
let ordering = ordering.into_iter().map(|(_val, idx)| idx).collect();
ordering
});
orderings.push({
let mut ordering = Vec::with_capacity(factor_count);
for i in 0..factor_count {
let mut l = 1;
let mut val = T::zero();
while l < factor_count && l < 3 && l < sorted_dists[i].len() {
let mut factors: Vec<T> = sorted_dists.iter().map(|inner_dist| inner_dist[0].1).collect();
factors[i] = sorted_dists[i][l].1;
let comb_val = combination_fn(&factors).unwrap_or(T::zero());
val = val + comb_val;
l += 1;
}
ordering.push((val, i));
}
ordering.sort_by(|(val_a, _idx_a), (val_b, _idx_b)| val_b.partial_cmp(&val_a).unwrap_or(Ordering::Equal));
let ordering = ordering.into_iter().map(|(_val, idx)| idx).collect();
ordering
});
orderings
}