August 6, 2018

Exercism Clojure Track - Run Length Encoding

Implement run-length encoding and decoding.

Run Length Encoding (RLE) is a simple form of data compression, where runs (consecutive data elements) are replaced by just one data value and count.

For example we can represent the original 53 characters with only 13.

"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"  ->  "12WB12W3B24WB"

RLE allows the original data to be perfectly reconstructed from the compressed data, which makes it a lossless data compression.

"AABCCCDEEEE"  ->  "2AB3CD4E"  ->  "AABCCCDEEEE"

For simplicity, you can assume that the unencoded string will only contain the letters A through Z (either lower or upper case) and whitespace. This way data to be encoded will never contain any numbers and numbers inside data to be decoded always represent the count for the following character.

Here we have live self-hosted Clojurescript code that defines a namespace and loads our testing framework. Placeholder functions are given to be completed to make the unit tests pass. Check out my solution and explanation in the next post.

(ns rle
  (:require [cljs.test :refer-macros [deftest is run-tests]]))
  
(defn run-length-encode
  "encodes a string with run-length-encoding"
  [plain-text]
  )

(defn run-length-decode
  "decodes a run-length-encoded string"
  [cipher-text]
  )
  
(deftest encode-empty-string
         (testing "encode an empty string"
                  (is (= (rle/run-length-encode "") ""))))

(deftest encode-single-characters-without-count
         (testing "encode single characters without count"
                  (is (= (rle/run-length-encode "XYZ") "XYZ"))))

(deftest encode-string-with-no-single-characters
         (testing "encode string with no single characters"
                  (is (= (rle/run-length-encode "AABBBCCCC") "2A3B4C"))))

(deftest encode-string-with-single-and-mixed-characters
         (testing "encode string with single and mixed characters"
                  (is (= (rle/run-length-encode "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB") "12WB12W3B24WB"))))

(deftest encode-multiple-whitespace
         (testing "encode string with whitespace characters mixed in it"
                  (is (= (rle/run-length-encode "  hsqq qww  ") "2 hs2q q2w2 "))))

(deftest encode-lowercase
         (testing "encode string with lowercase characters"
                  (is (= (rle/run-length-encode "aabbbcccc") "2a3b4c"))))

(deftest decode-empty-string
         (testing "decode empty string"
                  (is (= (rle/run-length-decode "") ""))))

(deftest decode-single-characters
         (testing "decode string with single characters only"
                  (is (= (rle/run-length-decode "XYZ") "XYZ"))))

(deftest decode-no-single-characters
         (testing "decode string with no single characters"
                  (is (= (rle/run-length-decode "2A3B4C") "AABBBCCCC"))))

(deftest decode-single-and-repeated-characters
         (testing "decode string with single and repeated characters"
                  (is (= (rle/run-length-decode "12WB12W3B24WB") "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"))))

(deftest decode-lowercase
         (testing "decode string with lowercase characters"
                  (is (= (rle/run-length-decode "2a3b4c") "aabbbcccc"))))

(deftest decode-mixed-whitespace
         (testing "decode string with mixed whitespace characters in it"
                  (is (= (rle/run-length-decode "2 hs2q q2w2 ") "  hsqq qww  "))))

(deftest consistency
         (testing "Encode a string and then decode it. Should return the same one."
                  (is (= (rle/run-length-decode (rle/run-length-encode "zzz ZZ  zZ")) "zzz ZZ  zZ"))))

(run-tests)
Tags: coding exercises Exercism Clojure