Receipt Bank Logo

Roman numeral to decimal number

Roman numeral to number converter

The Gauls have had enough of the Roman Empire. The Empire’s army is constantly attacking them. That’s not a problem for them - warding the Romans away is a piece of cake for them. The real problem is that for every attack all of the Gauls get mobilized. That’s not very efficient. One day their chief decided enough was enough. A plan was devised to bribe a Roman soldier to notify them of how large the attacking army is so they can mobilize just enough Gauls. Lean they wanted to be.

However, an issue was immediately apparent - Roman soldier always reported the numbers in roman literals. “Em-Em-El-Eks-Ai-Ai-Vi-Vi-Ai” was all he managed to mumble.

Help the Gauls by writing a method roman_to_number that converts roman literal to a number. Gauls, much like the Romans, have pretty poor typing skills, so keep it short.

Examples:

roman_to_number('III')    => 3
roman_to_number('XL')     => 40
roman_to_number('MMXVI')  => 2016

Leader board

The lower the score - the better. It is the shortest solution that wins.

If you're among the first 5 stop by out booth to claim your reward.
Winner!
Nickname: remi
   Score: 111 
def roman_to_number s
  l = d = 0
  s.each_char { |c|
    i = %w(I V X L C D M).zip([1,5,10,50,100,500,1e3]).to_h[c]
    d += i>l ? i-2*l : i
    l = i
  }
  d
end
Winner!
Nickname: Joskov
   Score: 111 
def roman_to_number n
  b = s = 0
  n.chars { |a| a = %w(I V X L C D M).zip([1, 5, 10, 50, 100, 500, 1e3]).to_h[a]; b = -b if b < a; s += b; b = a }
  s + b
end
Winner!
Nickname: janosch-jo
   Score: 112 
def roman_to_number s
  %w(CM M CD D XC C XL L IX X IV V I).zip(%w(900 1000 400 500 90 100 40 50 9 10 4 5 1)).map { |k,v| s.gsub! k, ?++v }
  eval s
end
Winner!
Nickname: rclavel
   Score: 112 
def roman_to_number a
    %w(CM CD XC XL IX IV M D C L X V I).zip(%w(900 400 90 40 9 4 1e3 500 100 50 10 5 1)).map { |x, y|
      a.gsub! x, '+' + y
    }
    eval a
  end
Winner!
Nickname: sashe
   Score: 116 
def roman_to_number s
  b = c = 0
  for d in 0...s.size
    e = {I: 1, X: 10, C: 100, M: 1000, V: 5, L: 50, D: 500}[:"#{s[-d-1]}"]
    b += e < c ? - e : e
    c = e
  end
  b
end
Nickname: Rosa
   Score: 120 
def roman_to_number r
  %w(CM CD XC XL IX IV M D C L X V I).zip(%w(900 400 90 40 9 4 1000 500 100 50 10 5 1)).map{ |l,v|
    r.gsub! l, '+' + v
  }
  eval r[1..-1]
end
Nickname: buhtum
   Score: 125 
def roman_to_number r
  x = Hash[*%w(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)]
  eval x.values_at(*r.scan(/#{x.keys * ?|}/)) * ?+
end
Nickname: timrogers
   Score: 136 
def roman_to_number r
n=0
%w(M CM D CD C XC L XL X IX V IV I).zip(%w(1000 900 500 400 100 90 50 40 10 9 5 4 1)).map { |l,v|
  (n += v.to_i
  r.slice! l) while r.index(l) == 0
}
n
end
Nickname: feri
   Score: 139 
def roman_to_number(d)
  s = i = 0
  c = {I:1, V:5, X:10, L:50, C:100, D:500, M:1000}
  d.each_char { |a|
    p = c[a.to_sym]
    i+=1
    s = p >= (d[i] ? c[d[i].to_sym] : 0) ? s+p : s-p
  }
  s
end
Nickname: ghaabor
   Score: 139 
def roman_to_number(r)
  h={M:1000,D:500,C:100,L:50,X:10,V:5,I:1}
  d = 0
  [*(r.split('').map { |c| h[c.to_sym] }), 0].each_cons(2){|x, y|
    x < y ? d -= x : d += x
  }
  d
end
Nickname: Ju
   Score: 147 
def roman_to_number(s)
    %w(M CM D CD C XC L XL X IX V IV I).zip(%w(1000 900 500 400 100 90 50 40 10 9 5 4 1)).inject(0) do |a, (k, v)|
    a += v.to_i and redo if s.gsub!(/^#{k}/, '')
    a
  end
end
Nickname: David
   Score: 148 
def roman_to_number l
  a = 0
  {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}.each { |k, v|
    x = /^#{k}/
    while l =~ x
      l.sub! x, ''
      a += v
    end
  }
  p a
end
Nickname: NDrive
   Score: 148 
def roman_to_number(r)
    a= 0
    %w[M CM D CD C XC L XL X IX V IV I].zip([1000,900,500,400,100,90,50,40,10,9,5,4,1]).each{|k, v| while r.index(k)==0
      a += v; r.slice!(k)
    end }
    a
  end
Nickname: yitsushi
   Score: 155 
def roman_to_number(s)
  r = {M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1}

  f = i = 0
  for o,v in r
    l = o.size
    f, i = f + v, i + l while s[i, l] == o.to_s
  end
  f
end
Nickname: emrox
   Score: 160 
def roman_to_number(r)
a=r.chars.map{|x|{?M=>1000,?D=>500,?C=>100,?L=>50,?X=>10,?V=>5,?I=>1}[x]};s=0;i=0;a.each{|v|s=a[i+1]&&a[i]<a[i+1]? s-a[i]: s+a[i];i=i+1};s
end
Nickname: kambata
   Score: 187 
def roman_to_number(e)
  h={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}
  a = e.scan(/(CM|CD|XC|XL|IX|IV|M|D|C|L|X|V|I)/).flatten(1)
  a.reduce(0){|v,r| h[r.to_sym]+v}
end
Nickname: Hanspolo
   Score: 187 
def roman_to_number(input)
  m = {'M'=>1000,'D'=>500,'C'=>100,'L'=>50,'X'=>10,'V'=>5,'I'=>1}
  input.split('').map.with_index{|s,i|
    i+1 < input.length && m[s] < m[input[i+1]] ? -1*m[s] : m[s]
  }.inject(&:+)
end
Nickname: bejczib
   Score: 206 
def roman_to_number(l)
  r,e,h = 0, '', {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}
  (h.each { |k, v| (r += v; e = l[0...k.size].to_s; break) if k.to_s == l[0...k.size] }; l.slice!(e)) while l.size > 0
  r
end
Nickname: Arie
   Score: 275 
def roman_to_number(roman_literal)
    m  = { 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" }
  t = 0
  m.each do |a, r|
    while roman_literal.start_with?(r)
      t += a
      roman_literal = roman_literal.slice(r.length, roman_literal.length)
    end
  end
  t
end