Move-to-front algorithm
Implemented using regular expressions:
func encode(str) {
var table = ('a'..'z' -> join)
str.chars.map { |c|
var s = ''
table.sub!(Regex('(.*?)' + c), {|s1| s=s1; c + s1})
s.len
}
}
func decode(nums) {
var table = ('a'..'z' -> join)
nums.map { |n|
var s = ''
table.sub!(Regex('(.{' + n + '})(.)'), {|s1, s2| s=s2; s2 + s1})
s
}.join
}
%w(broood bananaaa hiphophiphop).each { |test|
var encoded = encode(test)
say "#{test}: #{encoded}"
var decoded = decode(encoded)
print "in" if (decoded != test)
say "correctly decoded to #{decoded}"
}
Alternatively, implemented as a module, using arrays:
module MoveToFront {
define ABC = @("a".."z")
func m2f(ar,i) {
[ar.delete_index(i)] + ar
}
func encode(str) {
var ar = ABC+[]
gather {
str.each_char { |char|
take(var i = ar.index(char))
ar = m2f(ar, i)
}
}
}
func decode(indices) {
var ar = ABC+[]
gather {
indices.each { |i|
take ar[i]
ar = m2f(ar, i)
}
}.join
}
}
%w(broood bananaaa hiphophiphop).each { |test|
var encoded = MoveToFront::encode(test)
say "#{test}: #{encoded}"
var decoded = MoveToFront::decode(encoded)
print "in" if (decoded != test)
say "correctly decoded to #{decoded}"
}
Output:
broood: 1 17 15 0 0 5
correctly decoded to broood
bananaaa: 1 1 13 1 1 1 0 0
correctly decoded to bananaaa
hiphophiphop: 7 8 15 2 15 2 2 3 2 2 3 2
correctly decoded to hiphophiphop