homopolymer_compress/
lib.rs1#![warn(missing_docs)]
4
5pub fn homopolymer_compress<
7 'output,
8 Input: 'output + IntoIterator<Item = Item>,
9 Item: 'output + Eq + Clone,
10>(
11 input: Input,
12) -> impl 'output + Iterator<Item = Item> {
13 input
14 .into_iter()
15 .scan(None, |previous_item, item| {
16 if let Some(previous_item) = previous_item.as_mut() {
17 if *previous_item == item {
18 Some(None)
19 } else {
20 *previous_item = item.clone();
21 Some(Some(item))
22 }
23 } else {
24 *previous_item = Some(item.clone());
25 Some(Some(item))
26 }
27 })
28 .flatten()
29}
30
31#[cfg(test)]
32mod tests {
33 use crate::homopolymer_compress;
34
35 #[test]
36 fn test_homopolymer_compression() {
37 let input = b"ACAARRRTGGGTGTJASAAAI";
38 let expected = Vec::from_iter(b"ACARTGTGTJASAI".iter().cloned());
39 let actual = Vec::from_iter(homopolymer_compress(input.iter().cloned()));
40 assert_eq!(expected, actual);
41 }
42}