Run-length encoding

You are encouraged to solve this task according to the task description, using any language you may know.


Task

Given a string containing uppercase characters (A-Z), compress repeated 'runs' of the same character by storing the length of that run, and provide a function to reverse the compression.

The output can be anything, as long as you can recreate the input with it.



Example

 Input: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW
 Output: 12W1B12W3B24W1B14W


Note: the encoding step in the above example is the same as a step of the Look-and-say sequence.




import system'text;
import system'routines;
import extensions;
import extensions'text;
 
singleton compressor
{
    string compress(string s)
    {
        auto  tb := new TextBuilder();
        int count := 0;
        char current := s[0];
        s.forEach:(ch)
        {
            if (ch == current)
            {
                count += 1
            }
            else
            {
                tb.writeFormatted("{0}{1}",count,current);
                count := 1;
                current := ch
            }
        };
 
        tb.writeFormatted("{0}{1}",count,current);
 
        ^ tb
    }
 
    string decompress(string s)
    {
        auto tb := new TextBuilder();
        char current := $0;
        var a := new StringWriter();
        s.forEach:(ch)
        {
            current := ch;
            if (current.isDigit())
            {
                a.append(ch)
            }
            else
            {
                int count := a.toInt();
                a.clear();
 
                tb.fill(current,count)
            }
        };
 
        ^ tb
    }
}
 
public program()
{
    var s := "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW";
 
    s := compressor.compress(s);
    console.printLine(s);
 
    s := compressor.decompress(s);
    console.printLine(s)
}