Skip to content

Instantly share code, notes, and snippets.

@kvirani
Last active February 7, 2019 18:30
Show Gist options
  • Save kvirani/d4e11f7447ba62216331 to your computer and use it in GitHub Desktop.
Save kvirani/d4e11f7447ba62216331 to your computer and use it in GitHub Desktop.
Roman Numerals Exercise

We're going to write a method that converts an integer to its Roman numeral equivalent, i.e., 476 => 'CDLXXVI'.

For reference, these are the building blocks for how we encode numbers with Roman numerals:

I   1
V   5
X   10
L   50
C   100
D   500
M   1000

Roman Numerals as Representation

Have you ever seen a 5? I don't mean the symbol we write on a piece of paper or print to a screen, but an actual, honest-to-goodness 5?

Of course not. You've seen things that somehow embody five: five apples, five fingers, five weekdays on the calendar, a scrap of paper with "5" written on it, and so forth. Think of all the ways you can represent the integer 5.

Symbols like 5, "five", V, and IIIII are one way. If you asked a three-year-old, they might hold up the five fingers on their hand or pull out five pennies from their pocket. Computers encode numbers as a sequence of 0s and 1s called binary.

The map is not the territory, as they say.

Objectives

Old-school Roman numerals

In the early days of Roman numerals, the Roman's didn't bother with any of this new-fangled subtraction 'IX' nonsense. No sir, it was straight addition, biggest to littlest--so 9 was written 'VIIII' and so on.

Write a method to_roman that when passed an integer between 1 and 3000 (or so) returns a string containing the proper old-school Roman numeral.

In other words, to_roman(4) should return the string 'IIII'.

Make sure to test your method by passing it several inputs whose results you know. Test some simple numbers like to_roman(1) and more complicated numbers like to_roman(1646). This serves as a good sanity check.

Hint: Use the integer division / and modulus % methods.

Modern Roman numerals

Eventually, someone thought it would be terribly clever if putting a smaller number before a larger one meant you had to subtract the smaller one. As a result of this development, you must now suffer.

Rewrite your previous method to return the new-style Roman numerals so when someone calls to_roman(4), it should return the string 'IV'. You might want to run a script like this to make sure your program is working as intended:

puts "My totally sweet testing script"
puts ""
puts "input | expected | actual"
puts "------|----------|-------"
puts "4     | IV       | #{to_roman(4)}"
puts "9     | IX       | #{to_roman(9)}"
puts "13    | XIII     | #{to_roman(13)}"
puts "1453  | MCDLIII  | #{to_roman(1453)}"
puts "1646  | MDCXLVI  | #{to_roman(1646)}"

Examples

Arabic      Roman
     4         IV
     9         IX
    14        XIV
    44       XLIV
   944     CMXLIV
def to_roman(num)
# Your code here
end
# Drive code... this should print out trues.
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(6) == "VI"
# TODO: what other cases could you add to ensure your to_roman method is working?
@laurenachoo
Copy link

@numerals = [
["M", 1000],
["CM", 900],
["D", 500],
["C", 100],
["XC", 90],
["L", 50],
["XL", 40],
["X", 10],
["IX", 9],
["V", 5],
["IV", 4],
["I", 1],
]

def to_roman(num)
roman = ""
@numerals.each do |pair|
letter = pair[0]
value = pair[1]
quotient=(num / value)
roman += letter*quotient
num = num % value
end
return roman
end

puts to_roman(5) == "V"
puts to_roman(19) == "XIX"
puts to_roman(24) == "XXIV"
puts to_roman(29) == "XXIX"
puts to_roman(44) == "XLIV"
puts to_roman(555) == "DLV"
puts to_roman(890) == "DCCCXC"
puts to_roman(900) == "CM"
puts to_roman(1500) == "MD"
puts to_roman(1800) == "MDCCC"

Drive code... this should print out trues.

puts to_roman(1) == "I"

puts to_roman(3) == "III"

puts to_roman(6) == "VI"

TODO: what other cases could you add to ensure your to_roman method is working?

@laurenachoo
Copy link

@numerals = [
["M", 1000],
["CM", 900],
["D", 500],
["C", 100],
["XC", 90],
["L", 50],
["XL", 40],
["X", 10],
["IX", 9],
["V", 5],
["IV", 4],
["I", 1],
]

def to_roman(num)
roman = ""
@numerals.each do |pair|
letter = pair[0]
value = pair[1]
quotient=(num / value)
roman += letter*quotient
num = num % value
end
return roman
end

puts to_roman(5) == "V"
puts to_roman(19) == "XIX"
puts to_roman(24) == "XXIV"
puts to_roman(29) == "XXIX"
puts to_roman(44) == "XLIV"
puts to_roman(555) == "DLV"
puts to_roman(890) == "DCCCXC"
puts to_roman(900) == "CM"
puts to_roman(1500) == "MD"
puts to_roman(1800) == "MDCCC"

Drive code... this should print out trues.

puts to_roman(1) == "I"

puts to_roman(3) == "III"

puts to_roman(6) == "VI"

TODO: what other cases could you add to ensure your to_roman method is working?

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