use itertools::Itertools;
use num_traits::NumCast;
use std::hash::Hash;
use superslice::Ext;

pub fn compression<T: Clone + Ord + Hash + NumCast>(v: &mut Vec<T>) -> Vec<T> {
    let mut vals: Vec<T> = v.iter().cloned().unique().collect();
    let v_clone = v.clone();
    vals.sort();

    for (i, x) in v_clone.iter().enumerate() {
        v[i] = T::from(vals.lower_bound(x)).expect("T cannot convert from usize in compression");
    }

    vals
}

#[cfg(test)]
mod test_compression {
    use super::*;

    #[test]
    fn test_1() {
        let mut v = vec![55, 6, 432, 55, 98, 67, 6, 32];
        let vals = compression(&mut v);
        assert_eq!(&vals, &[6, 32, 55, 67, 98, 432]);
        assert_eq!(&v, &[2, 0, 5, 2, 4, 3, 0, 1]);
    }
}
