diff --git a/config.json b/config.json index 107355aa7..edf247b11 100644 --- a/config.json +++ b/config.json @@ -78,6 +78,16 @@ "panic" ] }, + { + "slug": "run-length-encoding", + "difficulty": 4, + "topics": [ + "string concatenation", + "conversion between string and int", + "use of primitive char", + "loop" + ] + }, { "slug": "hamming", "difficulty": 4, diff --git a/exercises/run-length-encoding/Cargo.lock b/exercises/run-length-encoding/Cargo.lock new file mode 100644 index 000000000..8114c0f53 --- /dev/null +++ b/exercises/run-length-encoding/Cargo.lock @@ -0,0 +1,4 @@ +[root] +name = "run-length-encoding" +version = "0.1.0" + diff --git a/exercises/run-length-encoding/Cargo.toml b/exercises/run-length-encoding/Cargo.toml new file mode 100644 index 000000000..3444428ac --- /dev/null +++ b/exercises/run-length-encoding/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "run-length-encoding" +version = "0.1.0" +authors = ["zombiefungus "] + +[dependencies] diff --git a/exercises/run-length-encoding/example.rs b/exercises/run-length-encoding/example.rs new file mode 100644 index 000000000..c03d5a7f8 --- /dev/null +++ b/exercises/run-length-encoding/example.rs @@ -0,0 +1,45 @@ +use std::cmp; + +pub fn encode(input: &str) -> String { + input + .chars() + .fold((String::new(), ' ', 0, 1), |(mut acc, last, last_n, pos), c| { + // acc = where answer is accumulated + // last = last character read + // last_n = accum count for last + if c == last { + if pos == input.len() { // end of string + acc += (last_n + 1).to_string().as_str(); + acc.push(c); + } + (acc, last, last_n + 1, pos + 1) + } + else { + if last_n > 1 { + acc += last_n.to_string().as_str(); + } + if last_n > 0 { // ignore initial last (single whitespace) + acc.push(last); + } + if pos == input.len() { // end of string + acc.push(c); + } + (acc, c, 1, pos + 1) + } + }).0 +} + +pub fn decode(input: &str) -> String { + input + .chars() + .fold((String::new(), 0), |(mut acc, last_n), c| { + if let Some(d) = c.to_digit(10) { + (acc, 10*last_n + d) + } + else { + acc += c.to_string() + .repeat(cmp::max(last_n, 1) as usize).as_str(); + (acc, 0) + } + }).0 +} diff --git a/exercises/run-length-encoding/src/lib.rs b/exercises/run-length-encoding/src/lib.rs new file mode 100644 index 000000000..e69de29bb diff --git a/exercises/run-length-encoding/tests/run-length-encoding.rs b/exercises/run-length-encoding/tests/run-length-encoding.rs new file mode 100644 index 000000000..143950e1e --- /dev/null +++ b/exercises/run-length-encoding/tests/run-length-encoding.rs @@ -0,0 +1,86 @@ +extern crate run_length_encoding as rle; + +// encoding tests + +#[test] +fn test_encode_empty_string() { + assert_eq!("", rle::encode("")); +} + +#[test] +#[ignore] +fn test_encode_single_characters() { + assert_eq!("XYZ", rle::encode("XYZ")); +} + +#[test] +#[ignore] +fn test_encode_string_with_no_single_characters() { + assert_eq!("2A3B4C", rle::encode("AABBBCCCC")); +} + +#[test] +#[ignore] +fn test_encode_single_characters_mixed_with_repeated_characters() { + assert_eq!("12WB12W3B24WB", rle::encode( + "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB")); +} + +#[test] +#[ignore] +fn test_encode_multiple_whitespace_mixed_in_string() { + assert_eq!("2 hs2q q2w2 ", rle::encode(" hsqq qww ")); +} + +#[test] +#[ignore] +fn test_encode_lowercase_characters() { + assert_eq!("2a3b4c", rle::encode("aabbbcccc")); +} + +// decoding tests + +#[test] +#[ignore] +fn test_decode_empty_string() { + assert_eq!("", rle::decode("")); +} + +#[test] +#[ignore] +fn test_decode_single_characters_only() { + assert_eq!("XYZ", rle::decode("XYZ")); +} + +#[test] +#[ignore] +fn test_decode_string_with_no_single_characters() { + assert_eq!("AABBBCCCC", rle::decode("2A3B4C")); +} + +#[test] +#[ignore] +fn test_decode_single_characters_with_repeated_characters() { + assert_eq!("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB", + rle::decode("12WB12W3B24WB")); +} + +#[test] +#[ignore] +fn test_decode_multiple_whitespace_mixed_in_string() { + assert_eq!(" hsqq qww ", rle::decode("2 hs2q q2w2 ")); +} + +#[test] +#[ignore] +fn test_decode_lower_case_string() { + assert_eq!("aabbbcccc", rle::decode("2a3b4c")); +} + +// consistency test + +#[test] +#[ignore] +fn test_consistency() { + assert_eq!("zzz ZZ zZ", rle::decode(rle::encode("zzz ZZ zZ").as_str())); +}