Receipt Bank Logo + Balkan Ruby Logo

Run length encoding

Run length encoding

Your room-mate, a molecular biologist, is always printing out pages of DNA sequences from his experiments. Since you are the in-house IT specialist, it is your responsibility to resupply the printer with paper when it runs out. Lately, your room-mate’s experiments have been getting bigger and bigger, so you’ve found yourself forced to go out for paper ever more often.

Finally, you’ve decided that enough is enough and that it is time to employ your technical prowess to make your life easier. Now, you’ve noticed that the DNA sequences being printed are composed of long repetitions of the same character, which makes them perfect for compression via run-length encoding. According to your estimates, this would decrease the size of the printed text by at least an order of magnitude and you will once again be free to watch re-runs of Firefly without interruptions!

All that is left for you to do is write a short program to encode messages. Being a generalist, you decide against hard-coding your encoder specifically for DNA sequences. You would rather solve this problem once and for all, so you want your program to encode arbitrary text composed of any letters. The encoding process itself is simple - replace all runs of repetitive characters with the number of repetitions followed by that character. Of course, this doesn’t apply for characters that do not repeat – they are left as they are.

Examples:

encode 'AAABCDDDDDEE'  # => '3ABC5D2E'
encode 'GATTACCCA'     # => 'GA2TA3CA'

Leader board

The lower the score - the better. It is the shortest solution that wins.

If you're ranked in the first 10, stop by our booth to claim your reward.
Winner!

Rank: 1
Nickname: Gosho337
Score: 45

def encode x
  x.gsub(/(.)\1+/){% #{$&.size}#$1 }
end
Winner!

Rank: 2
Nickname: dsbonev
Score: 46

def encode m
  m.gsub(/(.)\1+/) { $&.size.to_s + $1 }
end
Winner!

Rank: 2
Nickname: pesho
Score: 46

def encode s
  s.gsub(/(.)\1+/) { $&.size.to_s + $1 }
end
Winner!

Rank: 2
Nickname: dejaner
Score: 46

def encode s
  s.gsub(/(.)\1+/) { $&.size.to_s+$1 }
end
Winner!

Rank: 2
Nickname: ignisf
Score: 46

def encode m
  m.gsub(/(.)\1+/) { $&.size.to_s + $1 }
end
Winner!

Rank: 2
Nickname: Cindro
Score: 46

def encode s
  s.gsub(/(.)\1+/) { $&.size.to_s + $1 }
end
Winner!

Rank: 2
Nickname: ssk
Score: 46

def encode _
  _.gsub(/(.)\1*(?=\1)/) { $&.size + 1 }
end
Winner!

Rank: 2
Nickname: Tim
Score: 46

def encode s
  s.gsub(/(.)\1+/){ $&.size.to_s+$1 }
end
Winner!

Rank: 2
Nickname: buhtum
Score: 46

def encode s
  s.gsub(/(.)\1+/) { $&.size.to_s + $1 }
end
Winner!

Rank: 10
Nickname: Jure
Score: 48

def encode s
  s.gsub(/((.)\2+)/) { $1.size.to_s + $2 }
end
Winner!

Rank: 10
Nickname: hv
Score: 48

def encode _
  _.gsub(/(.)\1*(?=\1)/) { |m| m.size + 1 }
end
Winner!

Rank: 10
Nickname: Sve
Score: 48

def encode m
  m.gsub(/(.)\1+/) {|a| a.size.to_s + $1}
end

Rank: 13
Nickname: vizvamitra
Score: 50

def encode(m)
m.gsub(/((.)\2*(?=\2))/){$1.size+1}
end

Rank: 14
Nickname: popov
Score: 53

def encode(s)
  s.gsub(/(\w)\1+/) { |m| m.size.to_s + m[0] }
end

Rank: 15
Nickname: Sve&Evgeny
Score: 54

def encode m
  m.gsub(/(.)\1+/) { |a| "#{a.length}#{a[0]}" }
end

Rank: 16
Nickname: akseniyap
Score: 55

def encode m
  m.gsub(/(.)\1{1,}/){ |m| "#{m.size}#{m[0]}" }
end

Rank: 17
Nickname: cheater
Score: 59

def encode(m)
m.gsub(/((.)\2*)/){($1.size if $1[1]).to_s+$2}
end

Rank: 18
Nickname: mbd
Score: 66

def encode(message)
  message.gsub(/((.)\2+)/) { |m| m.size.to_s + m[0] }
end

Rank: 19
Nickname: Hiroyuki
Score: 72

def encode s
  s.chars.chunk(&:chr).map{|x,y|"#{y.size if y.size>1}"+x}.join
end

Rank: 20
Nickname: evg
Score: 83

def encode m
  m.scan(/(.)(\1{0,})/).map { |x| (x[1].size+1).to_s  + x[0] }.join.gsub(?1,'')
end

Rank: 21
Nickname: rb-bikezilla
Score: 86

def encode i
    i.scan(/#{[*?A..?Z].join(% +| )}/).flat_map{|g| [g.size,g[0]]}.join.tr(% 1 ,%  )
  end