Hone logo
Hone
Problems

Run-Length Encoding (RLE) Compression in Go

Run-Length Encoding (RLE) is a simple form of lossless data compression, particularly effective for data containing long runs of the same value. This challenge asks you to implement an RLE encoder and decoder in Go. Understanding and implementing RLE is a foundational step in grasping more complex compression algorithms.

Problem Description

You are tasked with creating a Go program that implements both encoding and decoding of data using Run-Length Encoding (RLE). The encoding process should take a byte slice as input and produce a new byte slice representing the RLE-encoded data. The decoding process should take an RLE-encoded byte slice as input and produce the original, uncompressed byte slice.

Encoding:

The encoding algorithm should iterate through the input byte slice. For each consecutive sequence of identical bytes, it should output the count of those bytes followed by the byte itself. The count is represented as a single byte (0-255).

Decoding:

The decoding algorithm should iterate through the encoded byte slice. For each byte, it should interpret the byte as a count. It should then read the next byte as the value to be repeated and append it to the output byte slice the specified number of times.

Key Requirements:

  • Encoding Function: Encode(data []byte) []byte - Takes a byte slice and returns the RLE-encoded byte slice.
  • Decoding Function: Decode(encodedData []byte) ([]byte, error) - Takes an RLE-encoded byte slice and returns the original byte slice. It should return an error if the encoded data is invalid (e.g., count exceeds 255, or the encoded data ends prematurely).
  • Error Handling: The Decode function must handle invalid encoded data and return an error.
  • Efficiency: While not a primary focus, strive for reasonably efficient implementations.

Examples

Example 1:

Input: []byte{'a', 'a', 'a', 'b', 'c', 'c', 'c', 'c'}
Output: []byte{3, 'a', 1, 'b', 3, 'c'}
Explanation: The input 'a', 'a', 'a' is encoded as 3, 'a'. 'b' is encoded as 1, 'b'. 'c', 'c', 'c', 'c' is encoded as 4, 'c'.

Example 2:

Input: []byte{3, 'a', 1, 'b', 3, 'c'}
Output: []byte{'a', 'a', 'a', 'b', 'c', 'c', 'c', 'c'}
Explanation: 3, 'a' decodes to 'a', 'a', 'a'. 1, 'b' decodes to 'b'. 3, 'c' decodes to 'c', 'c', 'c', 'c'.

Example 3: (Edge Case - Single Character)

Input: []byte{'x'}
Output: []byte{1, 'x'}
Explanation: A single character is encoded as 1, 'x'.

Example 4: (Edge Case - Empty Input)

Input: []byte{}
Output: []byte{}
Explanation: An empty input results in an empty output.

Constraints

  • The input data to Encode can be of any length (including empty).
  • The encoded data in Decode is assumed to be valid if the count is within the range 0-255.
  • The Decode function should return an error if the encoded data is malformed (e.g., count is out of range, or the encoded data ends prematurely without a complete count-value pair).
  • The output of Encode and Decode should be byte slices.
  • Performance is not a primary concern, but avoid excessively inefficient algorithms.

Notes

  • Consider using a loop to iterate through the input data.
  • Think about how to handle consecutive runs of the same byte.
  • Pay close attention to error handling in the Decode function. What happens if the encoded data is incomplete?
  • The encoding is not necessarily unique. For example, "aa" could be encoded as "2a" or "1a1a". Your implementation should produce a valid RLE encoding, not necessarily the only valid one.
  • The goal is to understand the core concept of RLE, not to create a highly optimized compression library.
Loading editor...
go