Skip to content

Commit 329f2d5

Browse files
committed
Added move_to_front_encoding implementation
1 parent b4aecf4 commit 329f2d5

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/compression/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
mod move_to_front;
12
mod run_length_encoding;
23

4+
pub use self::move_to_front::{move_to_front_decode, move_to_front_encode};
35
pub use self::run_length_encoding::{run_length_decode, run_length_encode};

src/compression/move_to_front.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// https://en.wikipedia.org/wiki/Move-to-front_transform
2+
3+
pub fn move_to_front_encode(text: &str) -> Vec<u8> {
4+
dbg!(text);
5+
let mut char_table: Vec<char> = (0..=255).map(|ch| ch as u8 as char).collect();
6+
let mut result = Vec::new();
7+
8+
for ch in text.chars() {
9+
if let Some(position) = char_table.iter().position(|&x| x == ch) {
10+
result.push(position as u8);
11+
char_table.remove(position);
12+
char_table.insert(0, ch);
13+
}
14+
}
15+
16+
result
17+
}
18+
19+
pub fn move_to_front_decode(encoded: &[u8]) -> String {
20+
let mut char_table: Vec<char> = (0..=255).map(|ch| ch as u8 as char).collect();
21+
let mut result = String::new();
22+
23+
for &pos in encoded {
24+
let ch = char_table[pos as usize];
25+
result.push(ch);
26+
char_table.remove(pos as usize);
27+
char_table.insert(0, ch);
28+
}
29+
30+
result
31+
}
32+
33+
#[cfg(test)]
34+
mod test {
35+
use super::*;
36+
37+
#[test]
38+
fn test_move_to_front_encode() {
39+
assert_eq!(move_to_front_encode(""), []);
40+
assert_eq!(move_to_front_encode("@"), [64]);
41+
assert_eq!(move_to_front_encode("aaba"), [97, 0, 98, 1]);
42+
assert_eq!(move_to_front_encode("aZ!"), [97, 91, 35]);
43+
assert_eq!(move_to_front_encode("banana"), [98, 98, 110, 1, 1, 1]);
44+
assert_eq!(move_to_front_encode("\0\n\t"), [0, 10, 10]);
45+
}
46+
47+
#[test]
48+
fn test_move_to_front_decode() {
49+
assert_eq!(move_to_front_decode(&[]), "");
50+
assert_eq!(move_to_front_decode(&[64]), "@");
51+
assert_eq!(move_to_front_decode(&[97, 0, 98, 1]), "aaba");
52+
assert_eq!(move_to_front_decode(&[97, 91, 35]), "aZ!");
53+
assert_eq!(move_to_front_decode(&[98, 98, 110, 1, 1, 1]), "banana");
54+
assert_eq!(move_to_front_decode(&[0, 10, 10]), "\0\n\t");
55+
}
56+
}

0 commit comments

Comments
 (0)