MCXI文字列(ACM)

30分プログラム、その51。id:zyxwvのマネをして、ACMの問題を解いてみよう。

http://www.acm-japan.org/past-icpc/domestic2005/C/C_ja.html

大事なところだけ、引用すると

文字 "m","c","x","i" は,それぞれ 1000,100,10,1 を表し, 数字 "2",...,"9" は,それぞれ 2,...,9 を表す. なお,この表記法はローマ数字とは関係ない.

たとえば,文字列

"5m2c3x4i", "m2c4i","5m2c3x"

は, 整数 5234 (=5*1000+2*100+3*10+4*1), 1204 (=1000+2*100+4*1), 5230 (=5*1000+2*100+3*10) にそれぞれ対応する. この例の中の "5m","2c","3x","4i" は, それぞれ 5000 (=5*1000),200 (=2*100),30 (=3*10),4 (=4*1) を表す.

irb> mcxi('xi')
11
irb> to_mcxi(11)
'xi'
# http://www.acm-japan.org/past-icpc/domestic2005/C/C_ja.html
MCXI={'m'=>1000,'c'=>100,'x'=>10,'i'=>1}
def mcxi(str)
  str.scan(/([2-9]?)([mcxi])/).inject(0){|n,x|
    count,chr = x
    n + (count == '' ? 1 : count.to_i) * MCXI[chr]
  }
end
 
def to_mcxi(n)
  MCXI.to_a.sort{|a,b| b[1]<=>a[1]}.inject(['',n]){|num,x|
    mcxi,rest = num
    chr,val = x

    if rest/val == 0 then
      [mcxi,rest % val]
    else
      [mcxi+(rest/val).to_s+chr,rest % val]
    end
  }[0]
end
 
#to_mcxi(mcxi('xi')+mcxi('x9i'))
  • Rubyでもパターンマッチが欲しいな
  • こういうパズル系はHaskellが便利だよな
  • Ruby勉強会@栄に参加しようか迷い中