use core::clone::Clone;
use core::cmp::Eq;
use core::fmt::Display;
use core::fmt::LowerHex;
use core::hash::Hash;
use std::collections::HashMap;
use std::fmt;
#[derive(Copy, Clone)]
pub struct Rle<T> {
pub part: T,
pub pos: usize,
pub cnt: usize,
pub max: bool,
}
impl<T: Display + LowerHex> fmt::Debug for Rle<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"<Rle@part:{:x},pos:{},cnt:{},max:{}>",
self.part, self.pos, self.cnt, self.max
)
}
}
impl<T: PartialEq> PartialEq<Rle<T>> for Rle<T> {
fn eq(&self, other: &Rle<T>) -> bool {
return self.part.eq(&other.part)
&& self.pos == other.pos
&& self.cnt == other.cnt
&& self.max == other.max;
}
fn ne(&self, other: &Self) -> bool {
!self.eq(other)
}
}
struct Last<T: Eq + Hash + Display + Copy + Clone> {
pub val: Option<Rle<T>>,
pub max_poses: HashMap<T, Vec<usize>>,
pub ret: Vec<Rle<T>>,
}
impl<T: Eq + Hash + Display + Copy + Clone + LowerHex> Last<T> {
pub fn handle_last(&mut self) {
if self.val.is_none() {
return;
}
let ref mut _last = self.val.as_mut().unwrap();
let max_rles = self
.max_poses
.entry(_last.part.clone())
.or_insert(Vec::new());
for idx in max_rles.clone() {
let ref mut prev = self.ret[idx];
if prev.cnt > _last.cnt {
_last.max = false;
} else if prev.cnt == _last.cnt {
} else if prev.cnt < _last.cnt {
prev.max = false;
}
}
max_rles.push(self.ret.len());
_last.pos = self.ret.len();
self.ret.push(_last.clone());
}
}
#[allow(dead_code)]
pub fn code<T: Eq + Hash + Display + Copy + Clone + LowerHex>(parts: &Vec<T>) -> Vec<Rle<T>> {
let mut last = Last {
val: None,
max_poses: HashMap::new(),
ret: Vec::new(),
};
for i in 0..parts.len() {
let ref part = parts[i];
if last.val.is_some() && last.val.unwrap().part == *part {
last.val.as_mut().unwrap().cnt += 1;
} else {
last.handle_last();
last.val = Some(Rle::<T> {
part: part.clone(),
pos: 0,
cnt: 1,
max: true,
});
}
}
last.handle_last();
return last.ret;
}