Skip to content

Instantly share code, notes, and snippets.

@rubiety
Created May 5, 2011 23:22
Show Gist options
  • Save rubiety/958180 to your computer and use it in GitHub Desktop.
Save rubiety/958180 to your computer and use it in GitHub Desktop.
Roman Numeral Ruby Quiz
#!/usr/bin/env ruby
MAPPINGS = {
"I" => 1,
"V" => 5,
"X" => 10,
"L" => 50,
"C" => 100,
"D" => 500,
"M" => 1000
}
def to_arabic(line)
parts = line.chomp.split("")
return 0 if parts.empty?
sorted_values = MAPPINGS.values.sort
sorted_names = sorted_values.map {|v| MAPPINGS.invert[v] }
part = parts[0]
next_part = parts[1]
if !next_part.nil? && sorted_names.index(part) < sorted_names.index(next_part)
addition = MAPPINGS[next_part] - MAPPINGS[part] || 0
pass_along = parts[2..-1]
else
addition = MAPPINGS[part] || 0
pass_along = parts[1..-1]
end
addition + to_arabic(pass_along.join)
end
def to_roman(line)
string = ""
sorted_values = MAPPINGS.values.sort
sorted_names = sorted_values.map {|v| MAPPINGS.invert[v] }
digits = line.chomp.split("")
digits.map {|d| d.to_i }.each_with_index do |digit, i|
position = digits.size - i
current_letter = MAPPINGS.invert[10 ** (position - 1)]
next_letter = sorted_names[sorted_names.index(current_letter) + 1]
next_next_letter = sorted_names[sorted_names.index(current_letter) + 2]
string << case digit
when 0..3 then current_letter * digit
when 4 then (current_letter + next_letter)
when 5..8 then next_letter + (current_letter * (digit - 5))
when 9 then current_letter + next_next_letter
end
end
string
end
$stdin.each_line do |line|
if line =~ /^\d+$/
puts to_roman(line)
elsif line =~ Regexp.new('^[' + MAPPINGS.keys.join + ']+$')
puts to_arabic(line)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment