Skip to content

Instantly share code, notes, and snippets.

@aseroff
Last active March 6, 2025 19:10
Show Gist options
  • Save aseroff/1dacc62a6f11f7eb4a44fd4ddf136996 to your computer and use it in GitHub Desktop.
Save aseroff/1dacc62a6f11f7eb4a44fd4ddf136996 to your computer and use it in GitHub Desktop.
Convert roman numerals into arabic numerals in place
# frozen_string_literal: true
# Enhance string class with roman numeral conversion methods
# To use, put `using RomanNumerals`
# @see https://docs.ruby-lang.org/en/master/syntax/refinements_rdoc.html
module RomanNumerals
refine String do
# Convert a roman numeral string into an arabic numeral
def to_arabic(zero_pad: 0)
result = 0
str = self
roman_mapping.each_value do |roman|
while str.start_with?(roman)
result += roman_mapping.invert[roman]
str = str.slice(roman.length, str.length)
end
end
result.zero? ? '' : result.to_s.rjust(zero_pad, '0')
end
# Find and replace roman numerals in a string with (zero-padded) arabic numerals
def convert_roman_in_place(zero_pad: 0)
gsub(/\bM{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\b/m) { |num| num.to_arabic(zero_pad:) }
end
private
# Roman numeral values
def roman_mapping
{
'1000': 'M',
'900': 'CM',
'500': 'D',
'400': 'CD',
'100': 'C',
'90': 'XC',
'50': 'L',
'40': 'XL',
'10': 'X',
'9': 'IX',
'5': 'V',
'4': 'IV',
'1': 'I'
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment