Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct RunLength<I>
- where
- I: Iterator,
- {
- iter: I,
- saved: Option<I::Item>,
- }
- impl<I> RunLength<I>
- where
- I: Iterator,
- {
- fn new(mut iter: I) -> Self {
- let saved = iter.next();
- Self { iter, saved }
- }
- }
- impl<I> Iterator for RunLength<I>
- where
- I: Iterator,
- I::Item: PartialEq,
- {
- type Item = (I::Item, usize);
- #[inline]
- fn next(&mut self) -> Option<Self::Item> {
- let c = self.saved.take().or_else(|| self.iter.next())?;
- let mut count = 1;
- while let Some(n) = self.iter.next() {
- if n == c {
- count += 1
- } else {
- self.saved = Some(n);
- break;
- }
- }
- Some((c, count))
- }
- #[inline]
- fn fold<B, F>(mut self, init: B, mut f: F) -> B
- where
- F: FnMut(B, Self::Item) -> B,
- {
- let mut c = match self.saved.take().or_else(|| self.iter.next()) {
- Some(c) => c,
- None => return init,
- };
- let mut count = 1;
- let mut value = init;
- for n in self.iter {
- if n == c {
- count += 1
- } else {
- value = f(value, (c, count));
- c = n;
- count = 1;
- }
- }
- f(value, (c, count))
- }
- }
- pub fn encode_tiny(data: &str) -> String {
- use std::fmt::Write;
- RunLength::new(data.chars()).fold(String::new(), |mut s, (c, count)| {
- match count {
- 1 => s.push(c),
- n => write!(&mut s, "{}{}", n, c).unwrap(),
- }
- s
- })
- }
- // encode (procedural) time: [18.343 ms 18.581 ms 18.838 ms]
- // Found 13 outliers among 100 measurements (13.00%)
- // 9 (9.00%) high mild
- // 4 (4.00%) high severe
- //
- // encode (tiny) time: [21.206 ms 21.486 ms 21.787 ms]
- // Found 5 outliers among 100 measurements (5.00%)
- // 5 (5.00%) high mild
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement