rubyローマ数字とアラビア数字を変換する方法

2075 ワード

def number_to_roma(n)
  #     
  number = [1,4,5,9,10,40,50,90,100,400,500,900,1000]
  roma   = ["I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"]
  hash = number.zip(roma).inject({}) {|r,ele| r[ele.first] = ele.last;r}
  #   、 、 、     ,        2  ,       10000     
  temp = 3.step(0,-1).inject([]) do |r,ele|
            r << n/(10**ele)
            n %= 10**ele
            r
          end
  #    ,       
  temp.reverse!
  #    
  result = ""
  3.step(0,-1).each do |i|
    #      ,   "M" *             
    if i == 3
      result << "M"*temp[i]
      next
    end
    #temp[i]*(10**i)                   ,        number   
    #    ,    hash             
    #     ,              5
    #    5,           (100,10,1)      (C,X,I) *            
    #    5,  (500,50,5)(D,L,V)       + (C,X,I) *       -5      
    if number.include?(temp[i]*(10**i))
      result << hash[temp[i]*(10**i)]
    else
      temp[i].to_i < 5 ? result << hash[10**i]*temp[i] : result << (hash[5*(10**i)]+hash[10**i]*(temp[i]-5))
    end
  end
  #    
  result
end
p number_to_roma(1661)
p number_to_roma(1990)
p number_to_roma(2008)
def roma_to_number(string)
  #     
  number = [1,4,5,9,10,40,50,90,100,400,500,900,1000]
  roma   = ["I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"]
  hash   = roma.zip(number).inject({}) {|r,ele| r[ele.first] = ele.last; r}
  #         
  reg    = /M|CM|D|CD|C|XC|L|XL|X|IX|V|IV|I/
  # scan         ,                  
  temp = string.scan(reg)
  #   ,              ,              。          。
  temp.uniq.inject(0) do |r,ele|
    r += temp.count(ele)*hash[ele]
  end
end
p roma_to_number("MDCLXI")
p roma_to_number("MCMXC")
p roma_to_number("MMVIII")