From 329f2d5270a059d2457357da017fc23260a8c6ba Mon Sep 17 00:00:00 2001 From: Divakar-2508 Date: Thu, 6 Mar 2025 10:38:54 +0530 Subject: [PATCH 1/4] Added move_to_front_encoding implementation --- src/compression/mod.rs | 2 ++ src/compression/move_to_front.rs | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/compression/move_to_front.rs diff --git a/src/compression/mod.rs b/src/compression/mod.rs index 7759b3ab8e4..7acbee56ec5 100644 --- a/src/compression/mod.rs +++ b/src/compression/mod.rs @@ -1,3 +1,5 @@ +mod move_to_front; mod run_length_encoding; +pub use self::move_to_front::{move_to_front_decode, move_to_front_encode}; pub use self::run_length_encoding::{run_length_decode, run_length_encode}; diff --git a/src/compression/move_to_front.rs b/src/compression/move_to_front.rs new file mode 100644 index 00000000000..eb954a29c06 --- /dev/null +++ b/src/compression/move_to_front.rs @@ -0,0 +1,56 @@ +// https://en.wikipedia.org/wiki/Move-to-front_transform + +pub fn move_to_front_encode(text: &str) -> Vec { + dbg!(text); + let mut char_table: Vec = (0..=255).map(|ch| ch as u8 as char).collect(); + let mut result = Vec::new(); + + for ch in text.chars() { + if let Some(position) = char_table.iter().position(|&x| x == ch) { + result.push(position as u8); + char_table.remove(position); + char_table.insert(0, ch); + } + } + + result +} + +pub fn move_to_front_decode(encoded: &[u8]) -> String { + let mut char_table: Vec = (0..=255).map(|ch| ch as u8 as char).collect(); + let mut result = String::new(); + + for &pos in encoded { + let ch = char_table[pos as usize]; + result.push(ch); + char_table.remove(pos as usize); + char_table.insert(0, ch); + } + + result +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_move_to_front_encode() { + assert_eq!(move_to_front_encode(""), []); + assert_eq!(move_to_front_encode("@"), [64]); + assert_eq!(move_to_front_encode("aaba"), [97, 0, 98, 1]); + assert_eq!(move_to_front_encode("aZ!"), [97, 91, 35]); + assert_eq!(move_to_front_encode("banana"), [98, 98, 110, 1, 1, 1]); + assert_eq!(move_to_front_encode("\0\n\t"), [0, 10, 10]); + } + + #[test] + fn test_move_to_front_decode() { + assert_eq!(move_to_front_decode(&[]), ""); + assert_eq!(move_to_front_decode(&[64]), "@"); + assert_eq!(move_to_front_decode(&[97, 0, 98, 1]), "aaba"); + assert_eq!(move_to_front_decode(&[97, 91, 35]), "aZ!"); + assert_eq!(move_to_front_decode(&[98, 98, 110, 1, 1, 1]), "banana"); + assert_eq!(move_to_front_decode(&[0, 10, 10]), "\0\n\t"); + } +} From fd47ae056a3e2a1534d5efc236da498bad4b0f5d Mon Sep 17 00:00:00 2001 From: Blaze Date: Thu, 20 Mar 2025 08:45:39 +0530 Subject: [PATCH 2/4] Update src/compression/move_to_front.rs Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com> --- src/compression/move_to_front.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compression/move_to_front.rs b/src/compression/move_to_front.rs index eb954a29c06..d3ca942a903 100644 --- a/src/compression/move_to_front.rs +++ b/src/compression/move_to_front.rs @@ -1,7 +1,6 @@ // https://en.wikipedia.org/wiki/Move-to-front_transform pub fn move_to_front_encode(text: &str) -> Vec { - dbg!(text); let mut char_table: Vec = (0..=255).map(|ch| ch as u8 as char).collect(); let mut result = Vec::new(); From da98a3fed84467e1d0078495193af05ba092254d Mon Sep 17 00:00:00 2001 From: Divakar-2508 Date: Thu, 20 Mar 2025 09:16:18 +0530 Subject: [PATCH 3/4] Removed unnescessary dbg!() and added macros for test_cases --- DIRECTORY.md | 1 + src/compression/move_to_front.rs | 41 ++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 3685ba5bf56..36c6563b9b6 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -46,6 +46,7 @@ * [Xor](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/xor.rs) * Compression * [Run Length Encoding](https://github.com/TheAlgorithms/Rust/blob/master/src/compression/run_length_encoding.rs) + * [Move-To-Front Encoding](https://github.com/TheAlgorithms/Rust/blob/master/src/compression/move_to_front.rs) * Conversions * [Binary To Decimal](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/binary_to_decimal.rs) * [Binary To Hexadecimal](https://github.com/TheAlgorithms/Rust/blob/master/src/conversions/binary_to_hexadecimal.rs) diff --git a/src/compression/move_to_front.rs b/src/compression/move_to_front.rs index d3ca942a903..c776a175814 100644 --- a/src/compression/move_to_front.rs +++ b/src/compression/move_to_front.rs @@ -1,7 +1,11 @@ // https://en.wikipedia.org/wiki/Move-to-front_transform +fn blank_char_table() -> Vec { + (0..=255).map(|ch| ch as u8 as char).collect() +} + pub fn move_to_front_encode(text: &str) -> Vec { - let mut char_table: Vec = (0..=255).map(|ch| ch as u8 as char).collect(); + let mut char_table = blank_char_table(); let mut result = Vec::new(); for ch in text.chars() { @@ -16,7 +20,7 @@ pub fn move_to_front_encode(text: &str) -> Vec { } pub fn move_to_front_decode(encoded: &[u8]) -> String { - let mut char_table: Vec = (0..=255).map(|ch| ch as u8 as char).collect(); + let mut char_table = blank_char_table(); let mut result = String::new(); for &pos in encoded { @@ -33,23 +37,24 @@ pub fn move_to_front_decode(encoded: &[u8]) -> String { mod test { use super::*; - #[test] - fn test_move_to_front_encode() { - assert_eq!(move_to_front_encode(""), []); - assert_eq!(move_to_front_encode("@"), [64]); - assert_eq!(move_to_front_encode("aaba"), [97, 0, 98, 1]); - assert_eq!(move_to_front_encode("aZ!"), [97, 91, 35]); - assert_eq!(move_to_front_encode("banana"), [98, 98, 110, 1, 1, 1]); - assert_eq!(move_to_front_encode("\0\n\t"), [0, 10, 10]); + macro_rules! test_mtf { + ($($name:ident: ($text:expr, $encoded:expr),)*) => { + $( + #[test] + fn $name() { + assert_eq!(move_to_front_encode($text), $encoded); + assert_eq!(move_to_front_decode(&$encoded), $text); + } + )* + } } - #[test] - fn test_move_to_front_decode() { - assert_eq!(move_to_front_decode(&[]), ""); - assert_eq!(move_to_front_decode(&[64]), "@"); - assert_eq!(move_to_front_decode(&[97, 0, 98, 1]), "aaba"); - assert_eq!(move_to_front_decode(&[97, 91, 35]), "aZ!"); - assert_eq!(move_to_front_decode(&[98, 98, 110, 1, 1, 1]), "banana"); - assert_eq!(move_to_front_decode(&[0, 10, 10]), "\0\n\t"); + test_mtf! { + empty: ("", vec![]), + single_char: ("@", vec![64]), + repeated_chars: ("aaba", vec![97, 0, 98, 1]), + mixed_chars: ("aZ!", vec![97, 91, 35]), + word: ("banana", vec![98, 98, 110, 1, 1, 1]), + special_chars: ("\0\n\t", vec![0, 10, 10]), } } From d3cd07e415aebdacd7dfbf35352c77047c9724a4 Mon Sep 17 00:00:00 2001 From: Divakar-2508 Date: Thu, 20 Mar 2025 09:44:18 +0530 Subject: [PATCH 4/4] replaced slices for Vec! --- src/compression/move_to_front.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compression/move_to_front.rs b/src/compression/move_to_front.rs index c776a175814..fe38b02ef7c 100644 --- a/src/compression/move_to_front.rs +++ b/src/compression/move_to_front.rs @@ -43,18 +43,18 @@ mod test { #[test] fn $name() { assert_eq!(move_to_front_encode($text), $encoded); - assert_eq!(move_to_front_decode(&$encoded), $text); + assert_eq!(move_to_front_decode($encoded), $text); } )* } } test_mtf! { - empty: ("", vec![]), - single_char: ("@", vec![64]), - repeated_chars: ("aaba", vec![97, 0, 98, 1]), - mixed_chars: ("aZ!", vec![97, 91, 35]), - word: ("banana", vec![98, 98, 110, 1, 1, 1]), - special_chars: ("\0\n\t", vec![0, 10, 10]), + empty: ("", &[]), + single_char: ("@", &[64]), + repeated_chars: ("aaba", &[97, 0, 98, 1]), + mixed_chars: ("aZ!", &[97, 91, 35]), + word: ("banana", &[98, 98, 110, 1, 1, 1]), + special_chars: ("\0\n\t", &[0, 10, 10]), } }