Skip to content

Instantly share code, notes, and snippets.

@amgando
Last active October 7, 2022 09:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save amgando/e4d5e7c5e9a49760cfa8 to your computer and use it in GitHub Desktop.
Save amgando/e4d5e7c5e9a49760cfa8 to your computer and use it in GitHub Desktop.
deliberate practice case study

Case Study: Roman Numerals

Learning Competencies

  • read and understand unfamiliar code
  • recognize recurring patterns in code
  • demonstrate familiarity with the syntax of your target language
  • execute and verify the performance of code against a strict specification
  • build endurance for confusion and uncertainty
  • demonstrate ability to engage in meaningful debate regarding code
  • develop an awareness for performance implications and maintanance costs
  • demonstrate the ability to create and execute a plan to build a software solution
  • develop an appreciation for deeper study and sharing learning outcomes

Summary

Please refer to this challenge for context: https://rosettacode.org/wiki/Roman_numerals

This case study is intended to melt your brain a little. So please be patient with yourself, your neighbor and the work while you get wildly curious about what's going on and don't stop til you drop -- whatever that means for your #lifestyle

You may want to try solving the original challenge first in any way you know how. This will help shape the holes in your head for the round, square and other odd-shaped pieces you'll discover during this learning experience.

[github] Also note at the bottom of this gist there may be a statement like "X other files aren't shown". This is a limitation of this github interface. To see all the files just download (or clone) this gist to get access to all the files in this case study. [/github]

Releases

Forget about the code for a second and let's consider process. How do you plan to move through the 40+ solutions to the programming problem you're working on? What's important? What's not?

Experts know what to ignore. That's a pretty important difference between them and a novice.

It saves them a lot of time, so they get more done with less.

Try this:

  1. Gather a group of people and pick a leader, mostly students but there can be other random people along for the ride. it's fun.
  2. Agree to move through this work together in a timed rhythm. The rhythm is designed to force a series of struggles.
  3. Some measure of playful faith might be required if you're the kind of person who prefers to control your own learning
  4. Here's the rhythm: (40+ solutions * (5 sec + 50 sec) + 3 solutions * (5 * 60 sec)) = 50 mins total
  • for 5 seconds: review each solution as quickly as possible. look for visual anchors, patterns, data structures, etc.
  • for 50 seconds: review each solution long enough to classify it. make up your own categories, compare and curate.
  • for 5 minutes: review the top 3 solutions more carefully. how you sort for top 3 is another key question.
  1. The cycle above can be repeated for other dimensions like swapping programming languages, machine constraints, pairing makeup, etc to help build a healthy heuristic for whatever your area of focus might be. if the goal of the experience is to learn a second programming language quickly, then running this exercise through commong problems in familiar languages to the same problems in unfamiliar code will fill in many gaps quickly. if the goal is self awareness then swapping pairs is great.
  2. once the journey is complete you can pick your next ambitious target like writing an original solution
  3. finally, the discussion is where a lot of the learning happens. consider using a consistent, proven approach like Thiagi's Six Step Debriefing process so you can focus all your attention on the student experience and record observations for deeper mentorship.

The whole experience can last for as little as 1 hour or as long as a week depending on the number of cycles, targets and dimensions of learning intended by the group.

Questions

Brainstorming on the following questions can be a good warmup activity as well. They help frame the experience.

establishing a baseline

  • does every solution run? how can you verify this?
  • do any solutions have bugs? how can you verify this?

breaking new ground

  • did you see any new syntax you didn't recognize? any new operators, expressions or methods?
  • can you decipher the syntax yourself from the context?
  • will you use this new syntax in your next project?
  • any new data structures? what are they?

recognizing patterns

  • how many fundamental solution patterns did you find?
  • how do you recognize them? are you sure? get worked up about it.

working with patterns

  • what can you learn from these different perspectives? are they really different? if so, why? debate. get worked up about it.
  • if you had to choose one, which one is the 'best' and why? discuss with your pair if you have one.

considering optimizations consider the patterns you noticed in the code ...

  • what are the performance implications of these patterns? how can you verify this?
  • what are the maintenance implications of these patterns? how can you be sure?

beginner's mind now that you've gone through all the above, open up a blank file and start again.

  • what are you thinking about now? as you plan your attack, what's most important? as you consider options, what's least important?
  • do you feel more or less confident than you did at first about your goal and ability to achieve it? what's different? discuss.
  • does knowing so much about how others solved this challenge constrain your thinking? if so, how can you reverse this effect?

Optimize Your Learning

Some people seem to appreciate hearing these so here's a list of follow ups:

  • document (and get ready to share) your aha! moments during this experience.
  • find a new pair-of-pairs to discuss your findings. debate. get worked up about it.
  • find a teacher or mentor and ask them to review your work. debate. get worked up about it.
  • write a blog post about what you've done here today. now that you care so much, share it.

Resources

If you're looking for a little hint on finding amazing resources, try this surveying method and see if it helps you somehow.

More about solving the roman numerals challenge

More about the value of reading code

More about the value of case studies

def to_roman(num)
ans = ''
thousands = num/1000
x = (num - (thousands)*1000)
hundreds = x /100
y = (x - (hundreds)*100)
tens = y/10
ones = (y - (tens)*10)
ans += 'M'*thousands
if hundreds == 9
ans += 'CM'
elsif hundreds >= 5
ans += "D"
ans += "C" * (hundreds-5)
elsif hundreds == 4
ans += "CD"
else
ans += "C" * hundreds
end
if tens ==9
ans += 'XC'
elsif tens >= 5
ans += "L"
ans += "X" * (tens-5)
elsif tens == 4
ans += "XL"
else
ans += "X" * tens
end
if ones ==9
ans += 'IX'
elsif ones >= 5
ans += "V"
ans += "I" * (ones-5)
elsif ones == 4
ans += "IV"
else
ans += "I" * ones
end
ans
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?
def to_roman(num)
roman_table = {1000 => "M", 900 => "CM", 500 => "D", 400 => "CD",
100 => "C", 90 => "XC", 50 => "L", 10 => "X",
9 => "IX", 5 => "V", 4 => "IV", 1 => "I" }
string = ""
roman_table.each do |key, value|
div_rem = num.divmod(key)
num_div_by = div_rem[0]
num_div_by.times do
string << value
end
num = div_rem[1]
end
string
end
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)}"
def to_roman(number)
number = number.to_i
roman_numbers = [
['M', 1000],
['CM', 900],
['D', 500],
['CD', 400],
['C', 100],
['LC', 90],
['L', 50],
['XL', 40],
['X', 10],
['IX', 9],
['V', 5],
['IV', 4],
['I', 1]
]
roman_numeral = ''
roman_numbers.each do |current_number|
current_number_times = number / current_number[1]
if current_number_times > 0
roman_numeral += current_number[0] * current_number_times
end
number %= current_number[1]
end
roman_numeral
end
puts "input | expected | actual"
puts "------|--------------|--------------"
puts "4 | IV | #{to_roman(4)}"
puts "9 | IX | #{to_roman(9)}"
puts "14 | XIV | #{to_roman(14)}"
puts "143 | CXLIII | #{to_roman(143)}"
puts "666 | DCLXVI | #{to_roman(666)}"
puts "1546 | MDXLVI | #{to_roman(1546)}"
puts "1646 | MDCXLVI | #{to_roman(1646)}"
puts "3353 | MMMCCCLIII | #{to_roman(3353)}"
def to_roman_old(num)
rom = "" if rom == nil
until num == 0 do
if num >= 1000
rom = "M"*(num/1000)
num = num % 1000
elsif num >= 500
rom = rom + "D"*(num/500)
num = num % 500
elsif num >= 100
rom = rom + "C"*(num/100)
num = num % 100
elsif num >= 50
rom = rom + "L"*(num/50)
num = num % 50
elsif num >= 10
rom = rom + "X"*(num/10)
num = num % 10
elsif num >= 5
rom = rom + "V"*(num/5)
num = num % 5
elsif num >= 1
rom = rom + "I"*num
num = num % 1
else
puts "That number is outside the range of this method. Try again."
end
end
return rom
end
def to_roman_new(num)
rom = "" if rom == nil
until num == 0 do
if num >= 1000
rom = "M"*(num/1000)
num = num % 1000
elsif num >= 500
rom = rom + "D"*(num/500)
num = num % 500
elsif num >= 100
if num/100 == 9
rom = rom + "CM"
elsif num/100 == 4
rom = rom + "CD"
else
rom = rom + "C"*(num/100)
end
num = num % 100
elsif num >= 50
rom = rom + "L"*(num/50)
num = num % 50
elsif num >= 10
if num/10 == 9
rom = rom + "XC"
elsif num/10 == 4
rom = rom + "XL"
else
rom = rom + "X"*(num/10)
end
num = num % 10
elsif num >= 5
if num == 9
rom = rom + "IX"
num = num - 9
else
rom = rom + "V"*(num/5)
num = num % 5
end
elsif num >= 1
if num == 4
rom = rom + "IV"
else
rom = rom + "I"*num
end
num = num % 1
else
puts "That number is outside the range of this method. Try again."
end
end
return rom
end
puts "My totally sweet testing script"
puts ""
puts "input | expected | actual"
puts "------|----------|-------"
puts "4 | IV | #{to_roman_new(4)}"
puts "9 | IX | #{to_roman_new(9)}"
puts "13 | XIII | #{to_roman_new(13)}"
puts "1453 | MCDLIII | #{to_roman_new(1453)}"
puts "1646 | MDCXLVI | #{to_roman_new(1646)}"
# TODO: what other cases could you add to ensure your to_roman method is working?
ROMAN_NUMERALS = {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"
}
# HACK
def to_roman(number)
output = ""
(number / ROMAN_NUMERALS["M"]).times do
output = output + "M"
end
number = number % ROMAN_NUMERALS["M"]
(number / ROMAN_NUMERALS["CM"]).times do
output = output + "CM"
end
number = number % ROMAN_NUMERALS["CM"]
(number / ROMAN_NUMERALS["D"]).times do
output = output + "D"
end
number = number % ROMAN_NUMERALS["D"]
(number / ROMAN_NUMERALS["CD"]).times do
output = output + "CD"
end
number = number % ROMAN_NUMERALS["CD"]
(number / ROMAN_NUMERALS["C"]).times do
output = output + "C"
end
number = number % ROMAN_NUMERALS["C"]
(number / ROMAN_NUMERALS["XC"]).times do
output = output + "XC"
end
number = number % ROMAN_NUMERALS["XC"]
(number / ROMAN_NUMERALS["L"]).times do
output = output + "L"
end
number = number % ROMAN_NUMERALS["L"]
(number / ROMAN_NUMERALS["XL"]).times do
output = output + "XL"
end
number = number % ROMAN_NUMERALS["XL"]
(number / ROMAN_NUMERALS["X"]).times do
output = output + "X"
end
number = number % ROMAN_NUMERALS["X"]
(number / ROMAN_NUMERALS["IX"]).times do
output = output + "IX"
end
number = number % ROMAN_NUMERALS["IX"]
(number / ROMAN_NUMERALS["V"]).times do
output = output + "V"
end
number = number % ROMAN_NUMERALS["V"]
(number / ROMAN_NUMERALS["IV"]).times do
output = output + "IV"
end
number = number % ROMAN_NUMERALS["IV"]
(number / ROMAN_NUMERALS["I"]).times do
output = output + "I"
end
number = number % ROMAN_NUMERALS["I"]
output
end
#Refactored
#def to_roman(number)
# output = ""
# ROMAN_NUMERALS.each do |key, value|
# divided = number / key
# # puts divided
# output += value * divided
# # puts output
# number -= divided * key
# end
# output
#end
# NOT A HACK BUT WE LIKE THE HACK BETTER
# def to_roman(number)
# thousands = (number / 1000)
# hundreds = (number % 1000 / 100)
# tens = (number % 100 / 10)
# ones = (number % 10 )
# roman_numeral = 'M' * thousands
# if hundreds == 9
# roman_numeral = roman_numeral + 'CM'
# elsif hundreds == 4
# roman_numeral = roman_numeral + 'CD'
# end
# else
# roman_numeral = roman_numeral + 'D' * (number % 1000 / 500)
# roman_numeral = roman_numeral + 'C' * (number % 500 / 100)
# end
# if tens == 9
# roman_numeral = roman_numeral + 'XC'
# elsif tens == 4
# roman_numeral = roman_numeral + 'XL'
# else
# roman_numeral = roman_numeral + 'L' * (number % 100 / 50)
# roman_numeral = roman_numeral + 'X' * (number % 50 / 10)
# end
# if ones == 9
# roman_numeral = roman_numeral + 'IX'
# elsif ones == 4
# roman_numeral = roman_numeral + 'IV'
# else
# roman_numeral = roman_numeral + 'V' * (num % 10 / 5)
# roman_numeral = roman_numeral + 'I' * (num % 5 / 1)
# end
# roman_numeral
# end
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)}"
def to_roman(num)
roman_string = ''
roman = {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"
}
roman.each do |k,v|
roman_string << v*(num/k)
num = num % k
end
roman_string
end
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)}"
puts "14: #{to_roman(14)}"
puts "44: #{to_roman(44)}"
puts "94: #{to_roman(94)}"
def to_roman(number)
roman = ''
mapping = {
:M => 1000,
:CM => 900,
:D => 500,
:MD => 400,
:C => 100,
:XC => 90,
:L => 50,
:XL => 40,
:X => 10,
:IX => 9,
:V => 5,
:IV => 4,
:I => 1,
}
while number > 0
mapping.each do |key, value|
while number >= value
if number >= value
roman += key.to_s
number -= value
end
end
end
end
roman
end
puts to_roman(1)
puts to_roman(3)
puts to_roman(6)
puts to_roman(101)
puts to_roman(1000)
puts to_roman(2506)
puts to_roman(9)
puts to_roman(150)
puts to_roman(88)
def to_roman(num)
result = ""
result += 'M' * (num / 1000)
result += 'D' * (num % 1000 / 500)
result += 'C' * (num % 500 / 100)
result += 'L' * (num % 100 / 50)
result += 'X' * (num % 50 / 10)
result += 'V' * (num % 10 / 5)
result += 'I' * (num % 5 / 1)
end
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(6) == "VI"
puts to_roman(1654) == "MDCLIIII"
# def to_modern_roman(num)
# result = ""
# result += 'M' * (num / 1000)
# result += 'DM'* (num % 1000 / 900)
# result += 'D' * (num % 900 / 500)
# result += 'CD'* (num % 500 / 400)
# result += 'C' * (num % 400 / 100)
# result += 'CL'* (num % 100 / 90)
# result += 'L' * (num % 90 / 50)
# result += 'XL'* (num % 50 / 40)
# result += 'X' * (num % 40 / 10)
# result += 'IX'* (num % 10 / 9)
# result += 'V' * (num % 10 / 5)
# result += 'IV'* (num % 5 / 4)
# result += 'I' * (num % 4 / 1)
# end
def to_modern_roman(num)
romans = ''
to_romans = { 'M' => 1000,
'DM' => 900,
'D' => 500,
'CD' => 400,
'C' => 100,
'CL' => 90,
'L' => 50,
'XL' => 40,
'X' => 10,
'IX' => 9,
'V' => 5,
'IV' => 4,
'I' => 1
}
to_romans.each do |roman, arabic|
romans += roman * (num / arabic)
num = num % arabic
end
return romans
end
puts "My totally sweet testing script"
puts ""
puts "input | expected | actual"
puts "------|----------|-------"
puts "4 | IV | #{to_modern_roman(4)}"
puts "9 | IX | #{to_modern_roman(9)}"
puts "13 | XIII | #{to_modern_roman(13)}"
puts "1453 | MCDLIII | #{to_modern_roman(1453)}"
puts "1646 | MDCXLVI | #{to_modern_roman(1646)}"
# # 0.upto(10) { |i| p to_modern_roman(i)}
def to_roman(num)
string = ""
string << "M" * (num / 1000)
string << "D" * ((num % 1000) / 500)
string << "C" * ((num % 500) / 100)
string << "L" * ((num % 100) / 50)
string << "X" * ((num % 50) / 10)
string << "V" * ((num % 10) / 5)
string << "I" * (num % 5)
string.gsub!("DCCCC", "CM") #900
string.gsub!("CCCC", "CD") #400
string.gsub!("LXXXX", "LC") #90
string.gsub!("XXXX", "XL") #40
string.gsub!("VIIII", "IX") #9
string.gsub!("IIII", "IV") #4
end
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?
# Brantley and Carter
def to_roman(num)
num_of_m = num / 1000
num %= 1000
num_of_d = num / 500
num %= 500
num_of_c = num / 100
num %= 100
num_of_l = num / 50
num %= 50
num_of_x = num / 10
num %= 10
num_of_v = num / 5
num %= 5
num_of_i = num / 1
num %= 1
roman_result = "M"*num_of_m + "D"*num_of_d + "C"*num_of_c + "L"*num_of_l + "X"*num_of_x + "V"*num_of_v + "I"*num_of_i
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?
def to_roman(num)
rm = { 1 => "I",
4 => "IV",
5 => "V",
9 => "IX",
10 => "X",
40 => "XL",
50 => "L",
90 => "XC",
100 => "C",
400 => "CD",
500 => "D",
900 => "CM",
1_000 => "M" }
numbers = [1_000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]
roman_numerable = ""
numbers.each do |number|
roman_numerable += rm[number] * (num / number)
num %= number
end
roman_numerable
end
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(4) == "IV"
puts to_roman(6) == "VI"
def to_roman(num)
roman_to_num = { "M" => 1_000,
"CM" => 900,
"D" => 500,
"CD" => 400,
"C" => 100,
"XC" => 90,
"L" => 50,
"XL" => 40,
"X" => 10,
"IX" => 9,
"V" => 5,
"IV" => 4,
"I" => 1 }
return "" if num == 0
roman_to_num.map { |roman, int| return roman + to_roman(num - int) if num >= int }
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?
#nice and refactored. Using a hash instead of repetition.
def to_roman(num)
roman_num = ""
roman_letters = { "M" => 1000,
"CM" => 900,
"D" => 500,
"CD" => 400,
"C" => 100,
"XC" => 90,
"L" => 50,
"XL" => 40,
"X" => 10,
"IX" => 9,
"V" => 5,
"IV" => 4,
"I" => 1 }
roman_letters.each do |roman, arabic|
roman_num += roman * (num / arabic)
num = num % arabic
end
roman_num
end
# Drive code... this should print out trues.
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(6) == "VI"
puts to_roman(34) == "XXXIV"
puts to_roman(49) == "XLIX"
puts to_roman(452) == "CDLII"
# TODO: what other cases could you add to ensure your to_roman method is working?
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 "34 | XXXIV | #{to_roman(34)}"
puts "1453 | MCDLIII | #{to_roman(1453)}"
puts "1646 | MDCXLVI | #{to_roman(1646)}"
def to_roman(num)
# Your code here
end
#Assumed rules for subtratcive case:
#I is allowed before V or X
#X before L or C
#C before D or M
def to_roman(num)
roman_sym=["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]
roman_val=[1000,900,500,400,100,90,50,40,10,9,5,4,1]
roman = ""
roman_sym.each_index do |i|
roman += roman_sym[i] * (num/roman_val[i])
num = num%roman_val[i]
end
return roman
end
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(6) == "VI"
puts to_roman(4) == "IV"
puts to_roman(9) == "IX"
puts to_roman(13) == "XIII"
puts to_roman(1453) == "MCDLIII"
puts to_roman(1646) == "MDCXLVI"
def to_roman(num)
conversion_table = { 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' }
roman_num = ''
conversion_table.each do |arabic, roman|
roman_num += roman * (num / arabic)
num %= arabic
end
return roman_num
end
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)}"
# 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?
def to_roman(num)
roman = []
(num/1000).times { roman.push "M" }
((num%1000) / 500).times { roman.push "D" }
((num%500) / 100).times { roman.push "C" }
((num%100) / 50).times { roman.push "L" }
((num%50) / 10).times { roman.push "X" }
((num%10) / 5).times { roman.push "V" }
((num%5) / 1).times { roman.push "I" }
roman.join
end
# Drive code... this should print out trues.
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(6) == "VI"
puts to_roman(3769)
def to_roman(integer)
string = ''
string = string + "M" * (integer / 1000)
integer = integer % 1000
string = string + "CM" * (integer / 900)
integer = integer % 900
string = string + "D" * (integer / 500)
integer = integer % 500
string = string + "CD" * (integer / 400)
integer = integer % 400
string = string + "C" * (integer / 100)
integer = integer % 100
string = string + "XC" * (integer / 90)
integer = integer % 90
string = string + "L" * (integer / 50)
integer = integer % 50
string = string + "XL" * (integer / 40)
integer = integer % 40
string = string + "X" * (integer / 10)
integer = integer % 10
string = string + "IX" * (integer / 9)
integer = integer % 9
string = string + "V" * (integer / 5)
integer = integer % 5
string = string + "IV" * (integer / 4)
integer = integer % 4
string = string + "I" * (integer / 1)
end
# Drive code... this should print out trues.
puts to_roman(4) == "IV"
puts to_roman(9) == "IX"
puts to_roman(13) == "XIII"
puts to_roman(1453) == "MCDLIII"
puts to_roman(1646) == "MDCXLVI"
# TODO: what other cases could you add to ensure your to_roman method is working?
def to_roman(num)
m = num / 1000
num -= m * 1000
d = num / 500
num -= d * 500
c = num / 100
num -= c * 100
l = num / 50
num -= l * 50
x = num / 10
num -= x * 10
v = num / 5
num -= v * 5
i = num / 1
('M'*m) + ('D'*d) + ('C'*c) +
('L'*l) + ('X'*x) + ('V'*v) + ('I'*i)
end
# Drive code... this should print out trues.
puts to_roman(1)
puts to_roman(3)
puts to_roman(6)
puts to_roman(101)
puts to_roman(1000)
puts to_roman(2506)
require 'minitest/spec'
require 'minitest/autorun'
describe Integer do
describe "#to_roman" do
it "should convert 1 to I" do
1.to_roman.must_equal "I"
end
end
it "should convert 3 to III" do
3.to_roman.must_equal "III"
end
it "should convert 6 to VI" do
6.to_roman.must_equal "VI"
end
it "should convert 9 to IX" do
9.to_roman.must_equal "IX"
end
it "should convert 20 to XX" do
20.to_roman.must_equal "XX"
end
it "should convert 1646 to MDCXLVI" do
1646.to_roman.must_equal "MDCXLVI"
end
end
class Integer
@@numerals = {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"}
def to_roman
output = ""
num_to_convert = self
@@numerals.each do |number,numeral|
output << numeral * (num_to_convert/number)
num_to_convert %= number
end
output
end
end
# Old School
def to_roman(arabic_integer)
roman_dictionary = {1000 => "M",
500 => "D",
100 => "C",
50 => "L",
10 => "X",
5 => "V",
1 => "I"}
roman_number = ""
roman_dictionary.each do |arabic, roman|
num_times = arabic_integer / arabic
roman_number += roman * num_times
arabic_integer -= num_times * arabic
end
roman_number
end
# New School
def to_roman(arabic_integer)
roman_dictionary = {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"}
roman_number = ""
roman_dictionary.each do |arabic, roman|
num_times = arabic_integer / arabic
roman_number += roman * num_times
arabic_integer -= num_times * arabic
end
roman_number
end
def to_roman(num)
roman_to_arabic = {
1000 => 'M',
500 => 'D',
100 => 'C',
50 => 'L',
10 => 'X',
5 => 'V',
1 => 'I'
}
roman_array = []
roman_to_arabic.each do |k, v|
roman_array << roman_to_arabic[k] * (num / k)
num = num - ((num / k) * k)
end
roman_array
end
#MODERN############################
def to_roman_modern(num)
roman_to_arabic = {
1000 => 'M',
900 => 'CM',
500 => 'D',
400 => 'CD',
100 => 'C',
90 => 'XC',
50 => 'L',
40 => 'XL',
10 => 'X',
9 => 'IX',
5 => 'V',
4 => 'M',
1 => 'I'
}
roman_array = []
roman_to_arabic.each do |k, v|
roman_array << roman_to_arabic[k] * (num / k)
num = num - ((num / k) * k)
end
roman_array.join
end
puts to_roman_modern(19)
def old_numerals(number)
(number / 1000).times do print "M" end
five_hundred = number % 1000
#puts five_hundred
(five_hundred / 500).times do print "D" end
one_hundred = five_hundred % 500
#puts one_hundred
(one_hundred / 100).times do print "C" end
fifty = one_hundred % 100
#puts fifty
(fifty / 50).times do print "L" end
ten = fifty % 50
#puts ten
(ten / 10).times do print "X" end
five = ten % 10
#puts five
(five / 5).times do print "V" end
one = five % 5
#puts one
if one <= 3
(one / 1).times do print "I" end
else
print "IV"
end
end
old_numerals(2634)
old_numerals(1) == "I"
old_numerals(3) == "III"
old_numerals(6) == "VI"
def roman_numerals(number)
numeral_output = ""
(number / 1000).times { numeral_output += "M" }
five_hundred = number % 1000
one_hundred = five_hundred % 500
if five_hundred > 900
numeral_output += "LD"
elsif five_hundred < 900 && five_hundred > 400
(five_hundred / 500).times { numeral_output += "D" } #900 = LD
end
if one_hundred <= 300
(one_hundred / 100).times { numeral_output += "C" } #400 = CD
else
numeral_output += "CD"
end
fifty = one_hundred % 100
if fifty < 90
(fifty / 50).times { numeral_output += "L" } #90 = VL
else
numeral_output += "VL"
end
ten = fifty % 50
if ten <= 30
(ten / 10).times { numeral_output += "X" } #40 = XL
else
numeral_output += "XL"
end
five = ten % 10
if five < 9
(five / 5).times do numeral_output += "V" end #9 = IX
else
numeral_output += "IX"
return numeral_output
end
one = five % 5
if one <= 3
(one / 1).times do numeral_output += "I" end
else
numeral_output += "IV" #4 = IV
end
return numeral_output
end
puts roman_numerals(4)
puts roman_numerals(9)
puts roman_numerals(13)
puts roman_numerals(1453)
puts roman_numerals(1646)
puts roman_numerals(1) == "I"
puts roman_numerals(3) == "III"
puts roman_numerals(6) == "VI"
#Oldschool Roman
def to_roman(num)
thousand = latin_number.divmod(1000)
fivehundreds = thousand[1].divmod(500)
hundreds = fivehundreds[1].divmod(100)
fifties = hundreds[1].divmod(50)
tenth = fifties[1].divmod(10)
fives = tenth[1].divmod(5)
arabic_numbers = 'M'*thousand[0] + 'D'*fivehundreds[0] + 'C'*hundreds[0] + 'L'*fifties[0] + 'X'*tenth[0] + 'V'*fives[0] + 'I'*fives[1]
puts arabic_numbers
end
Newschool Roman
def to_roman(latin_number)
thousand = latin_number.divmod(1000)
ninehundreds = thousand[1].divmod(900)
fivehundreds = ninehundreds[1].divmod(500)
fourhundreds = fivehundreds[1].divmod(400)
hundreds = fourhundreds[1].divmod(100)
ninties = hundreds[1].divmod(90)
fifties = ninties[1].divmod(50)
fourties = fifties[1].divmod(40)
tenth = fourties[1].divmod(10)
nines = tenth[1].divmod(9)
fives = nines[1].divmod(5)
fours = fives[1].divmod(4)
arabic_numbers = 'M'*thousand[0] + 'CM'*ninehundreds[0] + 'D'*fivehundreds[0] + 'CD'*fourhundreds[0] + 'C'*hundreds[0] + 'XC'*ninties[0] + 'L'*fifties[0] + 'XL'*fourties[0] + 'X'*tenth[0] + 'IX'*nines[0] + 'V'*fives[0] + 'IV'*fours[0] + 'I'*fours[1]
puts arabic_numbers
end
#old school
def to_roman(num)
if num <= 3000 && num >= 1
string = ""
thousands = num / 1000
string<<"M" * thousands
num -= (thousands * 1000)
five_hundred = num / 500
string<<"D" * five_hundred
num -= (five_hundred * 500)
hundred = num / 100
string<<"C" * hundred
num -= (hundred * 100)
fifty = num / 50
string<<"L" * fifty
num -= (fifty * 50)
ten = num / 10
string << "X" * ten
num -= (ten * 10)
five = num / 5
string << "V" * five
num -= (five * 5)
one = num / 1
string << "I" * one
num -= (one * 1)
puts string
end
end
#modern
def to_roman(num)
if num <= 3000 && num >= 1
string = ""
thousands = num / 1000
string << "M" * thousands
num -= (thousands * 1000)
nine_hundred = num / 900
string << "CM" * nine_hundred
num -= (nine_hundred * 900)
five_hundred = num / 500
string << "D" * five_hundred
num -= (five_hundred * 500)
four_hundred = num / 400
string << "CD" * four_hundred
num -= (four_hundred * 400)
hundred = num / 100
string << "C" * hundred
num -= (hundred * 100)
ninety = num / 90
string << "XC" * ninety
num -= (ninety * 90)
fifty = num / 50
string << "L" * fifty
num -= (fifty * 50)
forty = num / 40
string << "XL" * forty
num -= (forty * 40)
ten = num / 10
string << "X" * ten
num -= (ten * 10)
nine = num / 9
string << "IX" * nine
num -= (nine * 9)
five = num / 5
string << "V" * five
num -= (five * 5)
four = num / 4
string << "IV" * four
num -= (four * 4)
one = num / 1
string << "I" * one
num -= (one * 1)
puts string
end
end
def to_roman(number)
roman_numeral = ""
conversions = {
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",
}
while number > 0
conversions.each do |arabic, roman|
if number >= arabic
roman_numeral << roman
number -= arabic
end
end
end
roman_numeral
end
# This is my old roman numeral method!!!
# def to_roman(number)
# roman_numeral = ""
# roman_numeral << "M" * (number/1000)
# number = number % 1000
# roman_numeral << "D" * (number/500)
# number = number % 500
# roman_numeral << "C" * (number/100)
# number = number % 100
# roman_numeral << "L" * (number/50)
# number = number % 50
# roman_numeral << "X" * (number/10)
# number = number % 10
# roman_numeral << "V" * (number/5)
# number = number % 5
# roman_numeral << "I" * (number/1)
# number = number % 1
# roman_numeral
# 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?
# Old Roman Numerals
def to_roman(num)
array = []
array << 'M' * (num/1000)
num %= 1000
array << 'D' * (num/500)
num %= 500
array << 'C' * (num/100)
num %= 100
array << 'L' * (num/50)
num %= 50
array << 'X' * (num/10)
num %= 10
array << 'V' * (num/5)
num %= 5
array << 'I' * (num)
array.join
end
# Drive code... this should print out trues.
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(6) == "VI"
# New Roman Numerals
def to_roman(num)
roman_hash = {
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" }
array = []
roman_hash.each do |arabic , roman|
array << roman * (num/arabic)
num %= arabic
end
array.join
end
puts to_roman(1969)
puts to_roman(353)
puts to_roman(657)
def to_roman(num)
roman_translator = {
"M" => 1000,
"CM" => 900,
"D" => 500,
"CD" => 400,
"C" => 100,
"L" => 50,
"XL" => 40,
"X" => 10,
"IX" => 9,
"V" => 5,
"IV" => 4,
"I" => 1
}
roman = []
roman_translator.each do |roman_character, arabic|
roman << roman_character * (num / arabic)
num = num % arabic
end
roman.join
end
# Drive code... this should print out trues.
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(6) == "VI"
puts to_roman(1010) == "MX"
puts to_roman(1053) == "MLIII"
# TODO: what other cases could you add to ensure your to_roman method is working?
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)}"
def to_roman(num)
symbols = { 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'
}
roman_string = ''
symbols.each do |arabic, roman|
roman_string = roman_string + (roman * (num / arabic))
num = num % arabic
end
roman_string
end
# Drive code... this should print out trues.
puts to_roman(1) == "I"
puts to_roman(3) == "III"
puts to_roman(6) == "VI"
def to_roman(num)
output_string = ""
roman_numeral_dict = {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'}
roman_numeral_dict.sort.reverse.each do |english, roman|
number_of_romans = num/english
output_string = output_string + (roman*number_of_romans)
num = num % english
end
output_string
end
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)}"
puts "check"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment