use crate::{BTreeMap, Sort, Vec};
impl<T: Ord> Sort<&mut [T]> {
pub fn counting(self) -> Vec<usize>
where
T: Clone,
{
let mut counts = BTreeMap::new();
for item in self.0.iter() {
let count = counts.entry(item.clone()).or_insert(0);
*count += 1;
}
let freq: Vec<usize> = counts.values().copied().collect();
let mut i = 0;
for (item, &count) in counts.iter() {
for _ in 0..count {
self.0[i] = item.clone();
i += 1;
}
}
freq
}
pub fn merge(self)
where
T: Copy,
{
let len = self.0.len();
let mut buffer = Vec::with_capacity(len);
buffer.resize(len, self.0[0]);
helper::sort_merge_internal(self.0, &mut buffer);
}
}
mod helper {
use crate::is;
pub(super) fn sort_merge_internal<T: Ord + Copy>(slice: &mut [T], buffer: &mut [T]) {
let len = slice.len();
is![len <= 1, return];
let mid = len / 2;
sort_merge_internal(&mut slice[..mid], buffer);
sort_merge_internal(&mut slice[mid..], buffer);
sort_merge_merge(&slice[..mid], &slice[mid..], &mut buffer[..len]);
slice.copy_from_slice(&buffer[..len]);
}
pub(super) fn sort_merge_merge<T: Ord + Copy>(left: &[T], right: &[T], slice: &mut [T]) {
let (mut i, mut j, mut k) = (0, 0, 0);
while i < left.len() && j < right.len() {
is![
left[i] < right[j],
{
slice[k] = left[i];
i += 1;
},
{
slice[k] = right[j];
j += 1;
}
];
k += 1;
}
is![i < left.len(), slice[k..].copy_from_slice(&left[i..])];
is![j < right.len(), slice[k..].copy_from_slice(&right[j..])];
}
}