use num_traits::identities::Zero;
use std::iter::IntoIterator;
pub fn min_node_same_row( m : &usize ) -> usize {
let n = *m;
let mut k = 0;
let mut exp = 1;
while n >= k + exp {
k += exp;
exp *= 2;
}
k
}
pub fn parent_or_0( m : &usize ) -> usize {
let n = *m;
match n.is_zero() {
true => 0,
false => (n-1)/2
}
}
pub fn parent( m : &usize ) -> Option<usize> {
let n = *m;
match n.is_zero() {
true => None,
false => Some( (n-1)/2 )
}
}
pub fn child_a( m : &usize ) -> usize { 2 * m + 1 }
pub fn child_b( m : &usize ) -> usize { 2 * m + 2 }
pub fn sift_down<T, S>(heap: &mut [T], index: usize, mut less_than: S)
where S: FnMut(&T, &T) -> bool
{
debug_assert!(index <= heap.len());
let mut pos = index;
let mut child = child_a( &pos );
while pos < heap.len() && child < heap.len() {
let right = child + 1;
if right < heap.len() && less_than(&heap[right], &heap[child]) {
child = right;
}
if !less_than(&heap[child], &heap[pos]) {
return;
}
heap.swap(pos, child);
pos = child;
child = child_a( &pos );
}
}
pub fn heapify<T, S>(data: &mut [T], mut less_than: S)
where S: FnMut(&T, &T) -> bool
{
if data.is_empty() {
return; }
for i in (0..data.len() / 2).rev() {
sift_down(data, i, &mut less_than);
}
}
pub fn heapify_tail<T, S>(data: &mut [T], mut less_than: S, tail_base: &usize)
where S: FnMut(&T, &T) -> bool
{
if tail_base >= &data.len() {
return;
}
if data.len() < 2 {
return;
}
let mut right = data.len()-1;
let mut left = std::cmp::max( *tail_base, parent( &right ).unwrap() );
while right != 0 {
left = parent_or_0( &left ); right = parent_or_0( &right ); for i in ( left..( right + 1 ) ).rev() {
sift_down( data, i, &mut less_than );
}
}
}
pub fn bulk_insert< I, F > ( heap: &mut Vec< <I as IntoIterator>::Item >,
less_than: F,
iter: I
)
where I: IntoIterator,
F: FnMut(&<I as IntoIterator>::Item,
&<I as IntoIterator>::Item) -> bool
{
let base = heap.len();
heap.extend( iter.into_iter() );
heapify_tail( heap, less_than, &base);
}
pub fn pop< T, F> ( heap: &mut Vec <T>, less_than: F ) -> Option<T>
where F: FnMut( &T, &T) -> bool
{
if heap.len().is_zero() { return None }
let val = heap.swap_remove( 0 );
if !heap.is_empty() {
sift_down( heap, 0, less_than );
}
Some( val )
}
struct HeapIterator< T, F >
where F: FnMut( &T, &T) -> bool
{
heap: Vec< T >,
less_than: F
}
impl< T, F > Iterator for HeapIterator< T, F >
where F: FnMut( &T, &T) -> bool
{
type Item = T;
fn next( &mut self) -> Option< T > {
let less_than = &mut self.less_than;
pop( &mut self.heap, |p, q| less_than( p, q) )
}
}
use rand::{Rng};
pub fn randgen_n_of_k( n: usize, k: usize) -> Vec<usize> {
let mut rng = rand::thread_rng();
let v : Vec<usize> = (0..n).map(|_| rng.gen_range(0..k)).collect();
v
}
pub fn is_heapified< T, F >( vec: Vec<T>, mut less_than: F ) -> bool
where T: PartialOrd + Clone + std::fmt::Debug,
F: FnMut( &T, &T) -> bool
{
let mut heapified = true;
for pos in (1..vec.len()).rev() {
let par = parent( & pos ).unwrap();
if less_than( & vec[pos], & vec[par] ) {
heapified = false;
println!("{:?}", vec.clone());
println!("{:?}", pos.clone());
println!("{:?}", par.clone());
break;
}
}
heapified
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_heap_functions() {
let n = 10;
for _ in 0..n {
let vec = randgen_n_of_k( n, n/2);
let precedes = |p: &usize, q: &usize| p < q;
for a in 0..n {
for b in a..n {
let veca : Vec<usize> = ( 0..a ).map(|x| vec[x]).collect();
let vecb : Vec<usize> = ( a..b ).map(|x| vec[x]).collect();
let mut heap_a = veca.clone();
heapify( &mut heap_a, precedes );
assert!( is_heapified( heap_a.clone(), precedes ) );
let mut heap_b = heap_a.clone();
heap_b.extend( vecb.clone() );
heapify_tail( &mut heap_b, precedes, &a );
assert!( is_heapified( heap_b.clone(), precedes ) );
let mut heap_c = heap_a.clone();
bulk_insert( &mut heap_c, precedes, vecb.clone() );
assert!( is_heapified( heap_c.clone(), precedes ) );
let sorted_a : Vec<usize> = HeapIterator{ heap: heap_a.clone(), less_than: |p, q| &p < &q}.collect();
let sorted_b : Vec<usize> = HeapIterator{ heap: heap_b.clone(), less_than: |p, q| &p < &q}.collect();
let sorted_c : Vec<usize> = HeapIterator{ heap: heap_c.clone(), less_than: |p, q| &p < &q}.collect();
let mut sorted_true_a : Vec<usize> = (0..a).map(|x| vec[x]).collect();
let mut sorted_true_b : Vec<usize> = (0..b).map(|x| vec[x]).collect();
sorted_true_a.sort();
sorted_true_b.sort();
assert_eq!( sorted_a, sorted_true_a.clone() );
assert_eq!( sorted_b, sorted_true_b.clone() );
assert_eq!( sorted_c, sorted_true_b.clone() );
}
}
}
}
}