Run-length encoding

First solution:

func encode(str) {
  str.gsub(/((.)(\2*))/, {|a,b| "#{a.len}#{b}" })
}
 
func decode(str) {
  str.gsub(/(\d+)(.)/, {|a,b| b * a.to_i })
}

Output:

12W1B12W3B24W1B14W

Second solution, encoding the length into a byte:

func encode(str) {
    str.gsub(/(.)(\1{0,254})/, {|a,b| b.len+1 -> chr + a })
}
 
func decode(str) {
     var chars = str.chars
     var r = ''
     {|i|
         r += (chars[2*i + 1] * chars[2*i].ord)
     } << ^(chars.len//2)
     return r
}

Output:

"\fW\1B\fW\3B\30W\1B\16W"

Last updated