Skip to content

Instantly share code, notes, and snippets.

@tinomen
Created March 27, 2013 02:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tinomen/5251012 to your computer and use it in GitHub Desktop.
Save tinomen/5251012 to your computer and use it in GitHub Desktop.
2013-03 slc.rb problem 2
Convert a number between 1 and 4999 (integer only) to the roman numeral representation.
make a command line program that takes 1 argument as a number and outputs the roman numerals.
An online converter is available at http://www.onlineconversion.com/roman_numerals_advanced.htm
@aemadrid
Copy link

number = ARGV[0].to_i

def romanize(nr)
  return nr if nr > 5000
  if nr >= 1000
    "M" + romanize(nr - 1000)
  elsif nr >= 900
    "CM" + romanize(nr - 900)
  elsif nr >= 500
    "D" + romanize(nr - 500)
  elsif nr >= 400
    "CD" + romanize(nr - 400)
  elsif nr >= 100
    "C" + romanize(nr - 100)
  elsif nr >= 90
    "XC" + romanize(nr - 90)
  elsif nr >= 50
    "L" + romanize(nr - 50)
  elsif nr >= 40
    "XL" + romanize(nr - 40)
  elsif nr >= 10
    "X" + romanize(nr - 10)
  elsif nr >= 9
    "IX" + romanize(nr - 9)
  elsif nr >= 5
    "V" + romanize(nr - 5)
  elsif nr >= 4
    "IV" + romanize(nr - 4)
  elsif nr >= 1
    "I" + romanize(nr - 1)
  else
    ''
  end

end

puts romanize(number)

@cmaxw
Copy link

cmaxw commented Mar 27, 2013

# I DRYed this up. It was this same code repeated for each entry in the array.

puts "What number do you want converted?"
number = gets.chomp.to_i

answer = ""

[["M", 1000, "CM", 900],
 ["D", 500, "CD", 400],
 ["C", 100, "XC", 90],
 ["L", 50, "XL", 40],
 ["X", 10, "IX", 9],
 ["V", 5, "IV", 4]].each do |rtop, atop, rnext, anext|
  while number >= anext
    if number >= atop
      answer << rtop
      number -= atop
    else
      answer << rnext
      number -= anext
    end
  end
end


1.upto(number).each do |i|
  answer << "I"
end

puts answer

@statianzo
Copy link

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 convert(num, str='')
  return str if num.zero?
  key, val = NUMERALS.detect {|k, v| k <= num }
  convert num-key, str+val
end

p convert(ARGV[0].to_i)

@dandorman
Copy link

#! /usr/bin/env ruby

require 'nokogiri'
require 'open-uri'

number = ARGV[0].to_i
fail "Please provide a number between 1 and 4999" unless (1..4999).include?(number)

doc = Nokogiri::HTML(open("http://www.miniwebtool.com/roman-numerals-converter/?number=#{number}"))
doc.css('tr.tr1.p_1 td:nth-child(2)').each do |td|
  puts td.content
end

@aamax
Copy link

aamax commented Mar 27, 2013

describe "roman numerals" do
  it "should convert 1..3 to I" do
    (1..3).each do |i|
      convert(i).should == "I"*i
    end
  end

  it "should convert 1000 to M" do 
    convert(1000).should == "M"
  end

  it "should convert 1001 to MI" do 
    convert(1001).should == "MI"
  end

  it "should convert 500 to D" do 
    convert(500).should == "D"
  end
  it "should convert 100 to C" do 
    convert(100).should == "C"
  end
  it "should convert 50 to L" do 
    convert(50).should == "L"
  end
  it "should convert 10 to X" do 
    convert(10).should == "X"
  end
  it "should convert 5 to V" do 
    convert(5).should == "V"
  end
 it "should convert 4 to IV" do
   convert(4).should == "IV"
 end
 it "should convert 9 to IX" do
   convert(9).should == "IX"
 end

 it "should convert 40 to IL" do
   convert(40).should == "XL"
 end

 it "should convert 90 to XCIX" do
   convert(90).should == "XC"
 end
 it "should convert 400 to CD" do
   convert(400).should == "CD"
 end
 it "should convert 900 to CM" do
   convert(900).should == "CM"
 end

 it "should convert 4999 to MMMMCMXCIX" do
   convert(4999).should == "MMMMCMXCIX"
 end
 it "should convert 49 to XLIX" do
   convert(49).should == "XLIX"
 end

 it "should convert 99 to XCIX" do
   convert(99).should == "XCIX"
 end

end

def convert(val, carry="")
  if val >= 1000
    val -= 1000
    carry = convert(val, carry+"M")
  elsif val >= 900
    val -= 900
    carry = convert(val, carry+"CM")
  elsif val >= 500
    val -= 500
    carry = convert(val, carry+"D")
  elsif val >= 400
    val -= 400
    carry = convert(val, carry+"CD")
  elsif val >= 100
    val -= 100
    carry = convert(val, carry+"C")
  elsif val >= 90
    val -= 90
    carry = convert(val, carry+"XC")
  elsif val >= 50
    val -= 50
    carry = convert(val, carry+"L")
  elsif val >= 40
    val -= 40
    carry = convert(val, carry+"XL")    
  elsif val >= 10
    val -= 10
    carry = convert(val, carry+"X")
  elsif val == 9
    val -= 9
    carry = convert(val, carry+"IX")
  elsif val >= 5
    val -= 5
    carry = convert(val, carry+"V")
  elsif val == 4
    val -= 4
    carry = convert(val, carry+"IV")
  elsif val >= 1
    val -= 1
    carry = convert(val, carry+"I")
  end
  carry
end

@coderberry
Copy link

INCOMPLETE!!!

puts "Enter a number between 1 and 4999:"
num = gets.chomp.to_i



def number_hash(num)
  ret = {
    :m => 0,
    :d => 0,
    :c => 0,
    :l => 0,
    :x => 0,
    :v => 0,
    :i => 0
  }

  ret['m'] = num / 1000
  m_mod = num % 1000

  ret['d'] = m_mod / 500
  d_mod = m_mod % 500

  ret['c'] = d_mod / 100
  c_mod = d_mod % 100

  ret['l'] = c_mod / 50
  l_mod = c_mod % 50

  ret['x'] = l_mod / 10
  x_mod = l_mod % 10

  ret['v'] = x_mod / 5
  v_mod = x_mod % 5

  ret['i'] = v_mod / 1
  i_mod = v_mod % 1

  ret
end

def roman_numerals(hsh)
  ret = []
  keys = %w{ m d c l x v i }
  keys.each_with_index.each do |kk, i|
    vv = hsh[kk] # This is the number of occurances of this letter
    if vv == 4 && kk != 'm' # If it occurs 4 times, modify
      ret << kk + keys[i-1]
    else
      ret << kk * vv # e.g. CCC
    end
  end
  ret.join.upcase
end

hsh = number_hash(num)
puts roman_numerals(hsh)

@justinlyman
Copy link

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] ]

def romanize number
  num = number
  count = 0
  LETTERS.map{|l,v| count, num = num.to_i.divmod v; l*count}.join ''
end
puts 'Input number to Convert to Roman Numeral:'
input = gets
puts romanize(input)

@cmaxw
Copy link

cmaxw commented Mar 27, 2013

puts "What number do you want converted?"
number = gets.chomp.to_i

answer = "I" * number
answer.gsub!("I" * 1000, "M")
answer.gsub!("I" * 900, "CM")
answer.gsub!("I" * 500, "D")
answer.gsub!("I" * 400, "CD")
answer.gsub!("I" * 100, "C")
answer.gsub!("I" * 90, "XC")
answer.gsub!("I" * 50, "L")
answer.gsub!("I" * 40, "XL")
answer.gsub!("I" * 10, "X")
answer.gsub!("I" * 9, "IX")
answer.gsub!("I" * 5, "V")
answer.gsub!("I" * 4, "IV")


puts answer

@rickarubio
Copy link

not working, this is as far as I got

convert a number between 1 to 99 to the roman numberal representation

You must separate ones, tens, hundreds, and thousands as separate items.

You would not put more than one smaller number in front of a larger number to subtract.

A smaller number in front of a larger number means subtraction, all else means addition.

def convertTens(anInteger)
# as long as I have something on the left side of the decimal, I must have a tens position
if ( (anInteger / 10) > 0)
tensInteger = anInteger / 10
case tensInteger
when 1
tensNumeral = "X"
when 2
tensNumeral = "XX"
when 3
tensNumeral = "XXX"
when 4
tensNumeral = "XL"
when 5
tensNumeral = "L"
when 6
tensNumeral = "LX"
when 7
tensNumeral = "LXX"
when 8
tensNumeral = "LXXX"
when 9
tensNumeral = "XC"
end
end
return tensNumeral
end

def convertOnes(anInteger)
if ( (anInteger % 0.1) > 0)
puts "testing"
#problem is here with integer to floating point conversion
puts (anInteger % 0.1)
onesInteger = anInteger % 0.1
case onesInteger
when 1
onesNumeral = "I"
when 2
onesNumeral = "II"
when 3
onesNumeral = "III"
when 4
onesNumeral = "IV"
when 5
onesNumeral = "V"
when 6
onesNumeral = "VI"
when 7
onesNumeral = "VII"
when 8
onesNumeral = "VIII"
when 9
onesNumeral = "IX"
end
end
return onesNumeral
end

result = convertTens(99).to_s + convertOnes(99).to_s
puts result

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