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
The lower the score - the better. It is the shortest solution that wins.
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
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
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
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
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