Skip to content

Instantly share code, notes, and snippets.

@rfunduk
Created August 18, 2013 19:07
Show Gist options
  • Save rfunduk/6263373 to your computer and use it in GitHub Desktop.
Save rfunduk/6263373 to your computer and use it in GitHub Desktop.
Using only single numerals (eg, no definition in `map` for `40 => 'XL'`), convert an integer to it's equivalent roman numeral string. Run with `ruby int_to_roman_numerals.rb test` or `ruby int_to_roman_numerals.rb 1`
#!/usr/bin/env ruby
class Integer
def to_roman_numerals
num = self
map = {
1 => 'I',
5 => 'V',
10 => 'X',
50 => 'L',
100 => 'C',
500 => 'D',
1000 => 'M'
}
result = ""
# TODO: use `num` and `map` to determine `result`
result
end
end
if ARGV.length == 0 || ARGV[0] == 'test'
tests = {
0 => '',
1 => 'I',
3 => 'III',
4 => 'IV',
6 => 'VI',
9 => 'IX',
19 => 'XIX',
40 => 'XL',
47 => 'XLVII',
65 => 'LXV',
95 => 'XCV',
99 => 'XCIX',
200 => 'CC',
201 => 'CCI',
283 => 'CCLXXXIII',
420 => 'CDXX',
444 => 'CDXLIV',
499 => 'CDXCIX',
999 => 'CMXCIX',
1444 => 'MCDXLIV',
1867 => 'MDCCCLXVII',
1999 => 'MCMXCIX',
2000 => 'MM',
2113 => 'MMCXIII',
3333 => 'MMMCCCXXXIII'
}
errors = []
tests.entries.each do |input, expected|
if (r = input.to_roman_numerals) != expected
expected_str = "`#{expected}`".ljust(tests.values.map(&:length).max+2)
errors << " * Expected #{input.to_s.rjust(4)} to be #{expected_str} but got `#{r}`"
print 'F'
else
print '.'
end
end
if errors.any?
puts "\n#{errors.size} ERROR#{errors.size == 1 ? '' : 'S'}"
puts "#{errors.join("\n")}"
exit 1
else
puts "\n#{tests.size} PASSED"
end
else
input = ARGV[0].to_i
puts "`#{input}` in Roman Numerals: `#{input.to_roman_numerals}`"
end
@rfunduk
Copy link
Author

rfunduk commented Aug 22, 2013

What I came up with:

# first find whole thousands, five hundreds, one hundres, etc
map.entries.reverse.each do |int, numeral|
  while convert / int > 0
    result << numeral
    convert -= int
  end
end

# now substitute shorter variations where possible
prefixes = numerals[1..-2].join('')
result.gsub! /[#{prefixes}]?(.)\1{3}/ do |match|
  next match if match[0] == map[1000]

  # find the letter matched
  index = numerals.index(match[0])

  # figure out what the next numeral is
  next_numeral = numerals[index+1]
  # and what we need to subtract
  subtractor = match[1]

  "#{subtractor}#{next_numeral}"
end

@juanfal
Copy link

juanfal commented Jan 15, 2015

You use

tell application "Flint" to activate

but, what app y Flint… Ive tried to find everywhere… but nothing.
Thnaks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment