From f4af250c7d15782721d160cb1b9095419151f32e Mon Sep 17 00:00:00 2001 From: KOTP Date: Thu, 2 Nov 2023 15:42:49 -0400 Subject: [PATCH 1/6] Exercise: Run-length encoding (and decoding) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is currently draft/unfinished/work-in-progress. ref: #172 Typo, spacing error and expected/actual pattern Co-authored-by: András B Nagy <20251272+BNAndras@users.noreply.github.com> --- config.json | 7 ++ .../run-length-encoding/.docs/instructions.md | 21 ++++ .../run-length-encoding/.meta/config.json | 19 ++++ .../run-length-encoding/.meta/example.vim | 23 +++++ .../run_length_encoding.vader | 95 +++++++++++++++++++ .../run_length_encoding.vim | 33 +++++++ 6 files changed, 198 insertions(+) create mode 100644 exercises/practice/run-length-encoding/.docs/instructions.md create mode 100644 exercises/practice/run-length-encoding/.meta/config.json create mode 100644 exercises/practice/run-length-encoding/.meta/example.vim create mode 100644 exercises/practice/run-length-encoding/run_length_encoding.vader create mode 100644 exercises/practice/run-length-encoding/run_length_encoding.vim diff --git a/config.json b/config.json index e0c25e2..7f3eb71 100644 --- a/config.json +++ b/config.json @@ -329,6 +329,13 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + "slug": "run-length-encoding", + "name": "Run-Length Encoding", + "uuid": "1024a826-2f71-4833-9e96-59e0b0156f26", + "practices": [], + "prerequisites": [], + "difficulty": 3 }, { "slug": "rna-transcription", diff --git a/exercises/practice/run-length-encoding/.docs/instructions.md b/exercises/practice/run-length-encoding/.docs/instructions.md new file mode 100644 index 0000000..4757b87 --- /dev/null +++ b/exercises/practice/run-length-encoding/.docs/instructions.md @@ -0,0 +1,21 @@ +# Instructions + +Write the function that uses the run-length encoding and decoding algorithms to encode and decode a string. + +Run-length encoding (RLE) is a simple form of data compression where runs of consecutive identical data elements are replaced with one data value and count. + +Example: + +"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB" + +RLE allows the original data to be perfectly reconstructed from the compressed data, which makes it a lossless data compression. + +Example: + +"AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE" + +For simplicity, you can assume that the unencoded string will only contain the letters A through Z. (either upper or lower case) and whitespace. + +This means that the encoded data will not contain any numbers, so that any numbers contained within data to be decoded will always represent the count for the character that follows it. + + diff --git a/exercises/practice/run-length-encoding/.meta/config.json b/exercises/practice/run-length-encoding/.meta/config.json new file mode 100644 index 0000000..4ce96f7 --- /dev/null +++ b/exercises/practice/run-length-encoding/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "KOTP" + ], + "files": { + "solution": [ + "run_length_encoding.vim" + ], + "test": [ + "run_length_encoding.vader" + ], + "example": [ + ".meta/example.vim" + ] + }, + "blurb": "Implement run-length encoding and decoding.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Run-length_encoding" +} diff --git a/exercises/practice/run-length-encoding/.meta/example.vim b/exercises/practice/run-length-encoding/.meta/example.vim new file mode 100644 index 0000000..f44bd6f --- /dev/null +++ b/exercises/practice/run-length-encoding/.meta/example.vim @@ -0,0 +1,23 @@ +function! Decode(string) abort + return substitute(a:string, '\d\+\(\D\)', '\=submatch(1) . repeat(submatch(1), str2nr(submatch(0)))', 'g') +endfunction + +" TODO: Encode should accept a string, and return a string If it is given 'a' it +" should return 'a'. If it is given 'aa' it should return '2a'. +" If it is given 'aab' it should return '2ab'. If it is given 'aaab' it +" should return '3ab'. If it is given 'aaabb' it should return +" '3ab2'.QG7c0RlmLnkFlbJpROLJRriqwyOnXAdpBcYKQdlOSjtXgi +function! Encode(string) abort + let result = '' + let l:count = 1 + for i in range(len(a:string) - 1) + if a:string[i] ==# a:string[i + 1] + let l:count += 1 + else + let result .= l:count > 1 ? l:count . a:string[i] : a:string[i] + let l:count = 1 + endif + endfor + let result .= l:count > 1 ? l:count . a:string[-1] : a:string[-1] + return result +endfunction diff --git a/exercises/practice/run-length-encoding/run_length_encoding.vader b/exercises/practice/run-length-encoding/run_length_encoding.vader new file mode 100644 index 0000000..5e467fb --- /dev/null +++ b/exercises/practice/run-length-encoding/run_length_encoding.vader @@ -0,0 +1,95 @@ +Execute (encode empty text): + let g:actual = Encode('') + let g:expected = '' + AssertEqual g:expected, g:actual + +Execute (encode one letter): + let g:actual = Encode('A') + let g:expected = 'A' + AssertEqual g:expected, g:actual + +Execute (encode two letters that repeat): + let g:actual = Encode('aa') + let g:expected = '2a' + AssertEqual g:expected, g:actual + +Execute (encode three letters that repeat): + let g:actual = Encode('aaa') + let g:expected = '3a' + AssertEqual g:expected, g:actual + +Execute (encode abaabbbabaaa): + let g:actual = Encode('abaabbbabaaa') + let g:expected = 'ab2a3bab3a' + AssertEqual g:expected, g:actual + +Execute (encode a very long text): + let g:actual = Encode('aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz') + let g:expected = '2a2b2c2d2e2f2g2h2i2j2k2l2m2n2o2p2q2r2s2t2u2v2w2x2y2z2' + AssertEqual g:expected, g:actual + +Execute (encode empty text): + let g:actual = Encode('') + let g:expected '' + AssertEqual g:expected, g:actual + +Execute (encode single characters only are encoded without count): + let g:actual = Encode('XYZ') + let g:expected = 'XYZ' + AssertEqual g:expected, g:actual + +Execute (encode text with no single characters): + let g:actual = Encode('AABBBCCCC') + let g:expected = '2A3B4C' + AssertEqual g:expected, g:actual + +Execute (encode single characters with repeated characters): + let g:actual = Encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB') + let g:expected = '12WB12W3B24WB' + AssertEqual g:expected, g:actual + +Execute (encode multiple whitespace mixed in text): + let g:actual = Encode(' hsqq qww ') + let g:expected = '2 hs2q q2w2 ' + AssertEqual g:expected, g:actual + +Execute (encode lowercase characters): + let g:actual = Encode('aabbbcccc') + let g:expected = '2a3b4c' + AssertEqual g:expected, g:actual + +Execute (encode and then decode empty text gives empty text): + let g:actual = Decode(Encode('')) + let g:expected = '' + AssertEqual g:expected, g:actual + +Execute (decode single characters only): + let g:actual = Decode('XYZ') + let g:expected = 'XYZ' + AssertEqual g:expected, g:actual + +Execute (decode text with no single characters): + let g:actual = Decode('2A3B4C') + let g:expected = 'AABBBCCCC' + AssertEqual g:expected, g:actual + +Execute (decode single characters with repeated characters): + let g:actual = Decode('12WB12W3B24WB') + let g:expected = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB' + AssertEqual g:expected, g:actual + +Execute (decode multiple whitespace mixed in text): + let g:actual = Decode('2 hs2q q2w2 ') + let g:expected = ' hsqq qww ' + AssertEqual g:expected, g:actual + +Execute (decode lower case text): + let g:actual = Decode('2a3b4c') + let g:expected = 'aabbbcccc' + AssertEqual g:expected, g:actual + +Execute (encode followed by decode gives same text'): + let g:actual = Decode(Encode('zzz ZZ zZ')) + let g:expected = 'zzz ZZ zZ' + AssertEqual g:expected, g:actual + diff --git a/exercises/practice/run-length-encoding/run_length_encoding.vim b/exercises/practice/run-length-encoding/run_length_encoding.vim new file mode 100644 index 0000000..56e95ed --- /dev/null +++ b/exercises/practice/run-length-encoding/run_length_encoding.vim @@ -0,0 +1,33 @@ +"" +"" Write a function that will perform the algorithm that is known as "run-length +"" encoding". +"" +"" Run-length encoding (RLE) is a simple form of data compression where runs of +"" consecutive identical data elements are replaced with one data value and +"" count. +"" +"" Example: +"" +"" "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" -> "12WB12W3B24WB" +"" +"" RLE allows the original data to be perfectly reconstructed from the +"" compressed data, which makes it a lossless data compression. +"" +"" Example: +"" +"" "AABCCCDEEEE" -> "2AB3CD4E" -> "AABCCCDEEEE" +"" +"" For simplicity, you can assume that the unencoded string will only contain +"" the letters A through Z. (either upper or lower case) and whitespace. + +"" This means that the encoded data will not contain any numbers, so that any +"" numbers contained within data to be decoded will always represent the count +"" for the character that follows it. +"" +function! RunLengthDecoding(name) abort + " your code goes here +endfunction + +function! RunLengthEncoding(name) abort + " your code goes here +endfunction From ee621b0865956886d624fc84539854c9b7c2d778 Mon Sep 17 00:00:00 2001 From: KOTP Date: Sat, 25 Nov 2023 21:33:33 -0500 Subject: [PATCH 2/6] Applied patches from BNAndras --- config.json | 15 +- .../run-length-encoding/.meta/config.json | 3 + .../run-length-encoding/.meta/example.vim | 49 ++++-- .../run_length_encoding.vader | 159 +++++++----------- 4 files changed, 109 insertions(+), 117 deletions(-) diff --git a/config.json b/config.json index 7f3eb71..cf9b673 100644 --- a/config.json +++ b/config.json @@ -329,13 +329,6 @@ "practices": [], "prerequisites": [], "difficulty": 2 - }, - "slug": "run-length-encoding", - "name": "Run-Length Encoding", - "uuid": "1024a826-2f71-4833-9e96-59e0b0156f26", - "practices": [], - "prerequisites": [], - "difficulty": 3 }, { "slug": "rna-transcription", @@ -345,6 +338,14 @@ "prerequisites": [], "difficulty": 1 }, + { + "slug": "run-length-encoding", + "name": "Run-Length Encoding", + "uuid": "1024a826-2f71-4833-9e96-59e0b0156f26", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, { "slug": "robot-simulator", "name": "Robot Simulator", diff --git a/exercises/practice/run-length-encoding/.meta/config.json b/exercises/practice/run-length-encoding/.meta/config.json index 4ce96f7..7f06b7f 100644 --- a/exercises/practice/run-length-encoding/.meta/config.json +++ b/exercises/practice/run-length-encoding/.meta/config.json @@ -2,6 +2,9 @@ "authors": [ "KOTP" ], + "contributors": [ + "BNAndras" + ], "files": { "solution": [ "run_length_encoding.vim" diff --git a/exercises/practice/run-length-encoding/.meta/example.vim b/exercises/practice/run-length-encoding/.meta/example.vim index f44bd6f..8325122 100644 --- a/exercises/practice/run-length-encoding/.meta/example.vim +++ b/exercises/practice/run-length-encoding/.meta/example.vim @@ -1,23 +1,42 @@ function! Decode(string) abort - return substitute(a:string, '\d\+\(\D\)', '\=submatch(1) . repeat(submatch(1), str2nr(submatch(0)))', 'g') + let l:result = '' + let l:charCount = '' + for l:current in split(a:string, '\zs') + let l:codepoint = char2nr(l:current) + if (l:codepoint < 48 || l:codepoint > 57) + let l:number = max([l:charCount, 1]) + let l:result .= repeat(l:current, l:number) + let l:charCount = '' + else + let l:charCount .= l:current + endif + endfor + + return l:result endfunction -" TODO: Encode should accept a string, and return a string If it is given 'a' it -" should return 'a'. If it is given 'aa' it should return '2a'. -" If it is given 'aab' it should return '2ab'. If it is given 'aaab' it -" should return '3ab'. If it is given 'aaabb' it should return -" '3ab2'.QG7c0RlmLnkFlbJpROLJRriqwyOnXAdpBcYKQdlOSjtXgi function! Encode(string) abort - let result = '' - let l:count = 1 - for i in range(len(a:string) - 1) - if a:string[i] ==# a:string[i + 1] - let l:count += 1 + if len(a:string) == 0 + return '' + endif + + let l:result = '' + let l:charCount = 1 + let l:previous = '' + for l:current in split(a:string, '\zs') + if (l:current != l:previous) + let l:number = l:charCount > 1 ? l:charCount : '' + let l:result .= l:number . l:previous + + let l:previous = l:current + let l:charCount = 1 else - let result .= l:count > 1 ? l:count . a:string[i] : a:string[i] - let l:count = 1 + let l:charCount += 1 endif endfor - let result .= l:count > 1 ? l:count . a:string[-1] : a:string[-1] - return result + + let l:number = l:charCount > 1 ? l:charCount : '' + let l:result .= l:number . l:previous + + return l:result endfunction diff --git a/exercises/practice/run-length-encoding/run_length_encoding.vader b/exercises/practice/run-length-encoding/run_length_encoding.vader index 5e467fb..faa336e 100644 --- a/exercises/practice/run-length-encoding/run_length_encoding.vader +++ b/exercises/practice/run-length-encoding/run_length_encoding.vader @@ -1,95 +1,64 @@ -Execute (encode empty text): - let g:actual = Encode('') - let g:expected = '' - AssertEqual g:expected, g:actual - -Execute (encode one letter): - let g:actual = Encode('A') - let g:expected = 'A' - AssertEqual g:expected, g:actual - -Execute (encode two letters that repeat): - let g:actual = Encode('aa') - let g:expected = '2a' - AssertEqual g:expected, g:actual - -Execute (encode three letters that repeat): - let g:actual = Encode('aaa') - let g:expected = '3a' - AssertEqual g:expected, g:actual - -Execute (encode abaabbbabaaa): - let g:actual = Encode('abaabbbabaaa') - let g:expected = 'ab2a3bab3a' - AssertEqual g:expected, g:actual - -Execute (encode a very long text): - let g:actual = Encode('aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz') - let g:expected = '2a2b2c2d2e2f2g2h2i2j2k2l2m2n2o2p2q2r2s2t2u2v2w2x2y2z2' - AssertEqual g:expected, g:actual - -Execute (encode empty text): - let g:actual = Encode('') - let g:expected '' - AssertEqual g:expected, g:actual - -Execute (encode single characters only are encoded without count): - let g:actual = Encode('XYZ') - let g:expected = 'XYZ' - AssertEqual g:expected, g:actual - -Execute (encode text with no single characters): - let g:actual = Encode('AABBBCCCC') - let g:expected = '2A3B4C' - AssertEqual g:expected, g:actual - -Execute (encode single characters with repeated characters): - let g:actual = Encode('WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB') - let g:expected = '12WB12W3B24WB' - AssertEqual g:expected, g:actual - -Execute (encode multiple whitespace mixed in text): - let g:actual = Encode(' hsqq qww ') - let g:expected = '2 hs2q q2w2 ' - AssertEqual g:expected, g:actual - -Execute (encode lowercase characters): - let g:actual = Encode('aabbbcccc') - let g:expected = '2a3b4c' - AssertEqual g:expected, g:actual - -Execute (encode and then decode empty text gives empty text): - let g:actual = Decode(Encode('')) - let g:expected = '' - AssertEqual g:expected, g:actual - -Execute (decode single characters only): - let g:actual = Decode('XYZ') - let g:expected = 'XYZ' - AssertEqual g:expected, g:actual - -Execute (decode text with no single characters): - let g:actual = Decode('2A3B4C') - let g:expected = 'AABBBCCCC' - AssertEqual g:expected, g:actual - -Execute (decode single characters with repeated characters): - let g:actual = Decode('12WB12W3B24WB') - let g:expected = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB' - AssertEqual g:expected, g:actual - -Execute (decode multiple whitespace mixed in text): - let g:actual = Decode('2 hs2q q2w2 ') - let g:expected = ' hsqq qww ' - AssertEqual g:expected, g:actual - -Execute (decode lower case text): - let g:actual = Decode('2a3b4c') - let g:expected = 'aabbbcccc' - AssertEqual g:expected, g:actual - -Execute (encode followed by decode gives same text'): - let g:actual = Decode(Encode('zzz ZZ zZ')) - let g:expected = 'zzz ZZ zZ' - AssertEqual g:expected, g:actual - +Execute (encode - empty string): + let g:string = "" + let g:expected = "" + AssertEqual g:expected, Encode(g:string) + +Execute (encode - single characters only are encoded without count): + let g:string = "XYZ" + let g:expected = "XYZ" + AssertEqual g:expected, Encode(g:string) + +Execute (encode - string with no single characters): + let g:string = "AABBBCCCC" + let g:expected = "2A3B4C" + AssertEqual g:expected, Encode(g:string) + +Execute (encode - single characters mixed with repeated characters): + let g:string = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" + let g:expected = "12WB12W3B24WB" + AssertEqual g:expected, Encode(g:string) + +Execute (encode - multiple whitespace mixed in string): + let g:string = " hsqq qww " + let g:expected = "2 hs2q q2w2 " + AssertEqual g:expected, Encode(g:string) + +Execute (encode - lowercase characters): + let g:string = "aabbbcccc" + let g:expected = "2a3b4c" + AssertEqual g:expected, Encode(g:string) + +Execute (decode - empty string): + let g:string = "" + let g:expected = "" + AssertEqual g:expected, Decode(g:string) + +Execute (decode - single characters only): + let g:string = "XYZ" + let g:expected = "XYZ" + AssertEqual g:expected, Decode(g:string) + +Execute (decode - string with no single characters): + let g:string = "2A3B4C" + let g:expected = "AABBBCCCC" + AssertEqual g:expected, Decode(g:string) + +Execute (decode - single characters with repeated characters): + let g:string = "12WB12W3B24WB" + let g:expected = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" + AssertEqual g:expected, Decode(g:string) + +Execute (decode - multiple whitespace mixed in string): + let g:string = "2 hs2q q2w2 " + let g:expected = " hsqq qww " + AssertEqual g:expected, Decode(g:string) + +Execute (decode - lowercase string): + let g:string = "2a3b4c" + let g:expected = "aabbbcccc" + AssertEqual g:expected, Decode(g:string) + +Execute (decode - encode followed by decode gives original string): + let g:string = "zzz ZZ zZ" + let g:expected = "zzz ZZ zZ" + AssertEqual g:expected, Decode(Encode(g:string)) From 6e5259d4d455918b83e095e8f8bd388483ed082f Mon Sep 17 00:00:00 2001 From: Victor Goff Date: Mon, 27 Nov 2023 16:31:25 -0500 Subject: [PATCH 3/6] Short name for decode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: András B Nagy <20251272+BNAndras@users.noreply.github.com> --- exercises/practice/run-length-encoding/run_length_encoding.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/run-length-encoding/run_length_encoding.vim b/exercises/practice/run-length-encoding/run_length_encoding.vim index 56e95ed..57c6387 100644 --- a/exercises/practice/run-length-encoding/run_length_encoding.vim +++ b/exercises/practice/run-length-encoding/run_length_encoding.vim @@ -24,7 +24,7 @@ "" numbers contained within data to be decoded will always represent the count "" for the character that follows it. "" -function! RunLengthDecoding(name) abort +function! Decode(string) abort " your code goes here endfunction From c00e6280ced3939dfebea73e8758a708d56acb09 Mon Sep 17 00:00:00 2001 From: Victor Goff Date: Mon, 27 Nov 2023 16:31:44 -0500 Subject: [PATCH 4/6] Short name for encode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: András B Nagy <20251272+BNAndras@users.noreply.github.com> --- exercises/practice/run-length-encoding/run_length_encoding.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/run-length-encoding/run_length_encoding.vim b/exercises/practice/run-length-encoding/run_length_encoding.vim index 57c6387..5b102b8 100644 --- a/exercises/practice/run-length-encoding/run_length_encoding.vim +++ b/exercises/practice/run-length-encoding/run_length_encoding.vim @@ -28,6 +28,6 @@ function! Decode(string) abort " your code goes here endfunction -function! RunLengthEncoding(name) abort +function! Encode(string) abort " your code goes here endfunction From 7f9c3ed54468a603a5ecf37ea847676cd5be0834 Mon Sep 17 00:00:00 2001 From: Victor Goff Date: Mon, 27 Nov 2023 16:32:12 -0500 Subject: [PATCH 5/6] EOL for text files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: András B Nagy <20251272+BNAndras@users.noreply.github.com> --- exercises/practice/run-length-encoding/.meta/example.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/practice/run-length-encoding/.meta/example.vim b/exercises/practice/run-length-encoding/.meta/example.vim index 8325122..5bfcb1f 100644 --- a/exercises/practice/run-length-encoding/.meta/example.vim +++ b/exercises/practice/run-length-encoding/.meta/example.vim @@ -40,3 +40,4 @@ function! Encode(string) abort return l:result endfunction + From 65120c844b09fdcbaaf23eb4f487c1f50898d23d Mon Sep 17 00:00:00 2001 From: Victor Goff Date: Mon, 27 Nov 2023 16:32:33 -0500 Subject: [PATCH 6/6] EOL for text files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: András B Nagy <20251272+BNAndras@users.noreply.github.com> --- exercises/practice/run-length-encoding/run_length_encoding.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/exercises/practice/run-length-encoding/run_length_encoding.vim b/exercises/practice/run-length-encoding/run_length_encoding.vim index 5b102b8..d265172 100644 --- a/exercises/practice/run-length-encoding/run_length_encoding.vim +++ b/exercises/practice/run-length-encoding/run_length_encoding.vim @@ -31,3 +31,4 @@ endfunction function! Encode(string) abort " your code goes here endfunction +