Skip to content

Instantly share code, notes, and snippets.

@Mon-Ouie
Created December 28, 2009 12:03
Show Gist options
  • Save Mon-Ouie/264647 to your computer and use it in GitHub Desktop.
Save Mon-Ouie/264647 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'optparse'
module RLE
class << self
def use_flag(val)
@flag = val
end
def max_instances(max)
@max_instances = max
end
def compress(string)
string.split("\n").inject("") do |output, str|
str.chomp!
last_char = nil
count = 0
(0...str.size).each do |i|
if last_char
if last_char == str[i]
count += 1
if count == @max_instances
output += "#{@max_instances}#{@flag}#{last_char}"
count = 0
elsif i == str.size - 1
output += "#{count == 1 ? "" : count}#{@flag}#{last_char}"
end
else
output += "#{count == 1 ? "" : count}#{@flag}#{last_char}"
last_char = str[i]
count = 1
if i == str.size - 1
output += "#{count == 1 ? "" : count}#{@flag}#{last_char}"
end
end
else
last_char = str[i]
count = 1
if i == str.size - 1
output += "#{count == 1 ? "" : count}#{@flag}#{last_char}"
end
end
end
output + "\n"
end
end
def uncompress(string)
str.split("\n").inject("") do |output, line|
raise "Invalid string" unless line =~ /^((\d+)?#{@flag}.)*$/
line.scan(/(\d+)?#{@flag}(.)/).inject(output) { |str, match|
str + (match[1] * (match[0] ? match[0].to_i : 1))
} + "\n"
end
end
end
use_flag "@"
max_instances 9
end
if __FILE__ == $0
options = {
:input_file => $stdin,
:output_file => $stdout,
:flag => "@",
:max_instances => 9,
:compress => true
}
opts_parser = OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [options]"
opts.on("-i", "--input [filename]", String,
"Change the input file (default: stdin)") do |file|
options[:input_file] = File.open(file)
end
opts.on("-o", "--output [filename]", String,
"Change the output file (default: stdout)") do |file|
options[:output_file] = File.open(file, 'w')
end
opts.on("-f", "--flag [character]", String,
"Change the flag used as separator (default: @)") do |flag|
raise "Flag's size has to be one." if flag.size != 1
raise "Flag cannot be a digit." if flag =~ /\d/
options[:flag] = flag
end
opts.on("-m", "--max-instances [integer]", Integer,
"Change the flag used as separator (default: 9)") do |max|
options[:max_instances] = max
end
opts.on("--op [operation]", [:compress, :uncompress],
"Change the operation (compress, uncompress)") do |val|
options[:compress] = val == :compress
end
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
end
opts_parser.parse!
RLE.use_flag options[:flag]
RLE.max_instances options[:max_instances]
str = options[:input_file].read
if options[:compress]
options[:output_file].print RLE.compress(str)
else
options[:output_file].print RLE.uncompress(str)
end
options[:output_file].close if options[:output_file] != $stdout
options[:input_file].close if options[:input_file] != $stdin
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment