#!/usr/bin/ruby # Compress a string to a list of output symbols. func compress(String uncompressed) -> Array { # Build the dictionary. var dict_size = 256; var dictionary = Hash.new; 0 .. dict_size-1 -> each { |i| dictionary{i.chr} = i.chr; }; var w = ''; var result = []; uncompressed.each { |c| var wc = w+c; if (dictionary.has_key(wc)) { w = wc; } else { result.append(dictionary{w}); # Add wc to the dictionary. dictionary{wc} = dict_size; dict_size++; w = c; } }; # Output the code for w. if (w != '') { result.append(dictionary{w}); }; return result; }; # Decompress a list of output ks to a string. func decompress(Array compressed) -> String { # Build the dictionary. var dict_size = 256; var dictionary = Hash.new; 0 .. dict_size-1 -> each { |i| dictionary{i.chr} = i.chr; }; var w = compressed.shift; var result = w; compressed.each { |k| var entry; if (dictionary.has_key(k)) { entry = dictionary{k}; } elsif (k == dict_size) { entry = w+w.substr(0,1); } else { die "Bad compressed k: #{k}"; }; result += entry; # Add w+entry[0] to the dictionary. dictionary{dict_size} = w+entry.substr(0,1); dict_size++; w = entry; }; return result; }; # How to use: var compressed = compress('TOBEORNOTTOBEORTOBEORNOT'); say compressed.join(' '); var decompressed = decompress(compressed); say decompressed;