use alloc::vec::Vec;
use core::cmp::Ordering;
pub fn max<T: Ord>(iter: impl IntoIterator<Item = T>, n: usize) -> Vec<T> {
max_by(iter, n, T::cmp)
}
pub fn min<T: Ord>(iter: impl IntoIterator<Item = T>, n: usize) -> Vec<T> {
min_by(iter, n, T::cmp)
}
pub fn max_by<T>(
iter: impl IntoIterator<Item = T>,
n: usize,
mut cmp: impl FnMut(&T, &T) -> Ordering,
) -> Vec<T> {
if n == 0 {
return Vec::new();
}
let mut right = iter.into_iter();
let mut left = right.by_ref().take(n).collect::<Vec<_>>();
crate::make_min_heap(&mut left, &mut cmp);
for i in right {
let min = &mut left[0];
if cmp(&i, min).is_gt() {
*min = i;
crate::sift_down(&mut left, 0, &mut cmp);
}
}
crate::sort_min_heap(&mut left, &mut cmp);
left
}
pub fn min_by<T>(
iter: impl IntoIterator<Item = T>,
n: usize,
mut cmp: impl FnMut(&T, &T) -> Ordering,
) -> Vec<T> {
max_by(iter, n, |a, b| cmp(b, a))
}
pub fn max_by_key<T, K: Ord>(
iter: impl IntoIterator<Item = T>,
n: usize,
mut f: impl FnMut(&T) -> K,
) -> Vec<T> {
max_by(iter, n, |a, b| f(a).cmp(&f(b)))
}
pub fn min_by_key<T, K: Ord>(
iter: impl IntoIterator<Item = T>,
n: usize,
mut f: impl FnMut(&T) -> K,
) -> Vec<T> {
min_by(iter, n, |a, b| f(a).cmp(&f(b)))
}