fork download
  1. #!ruby
  2.  
  3. =begin
  4. 【問】ある数字 n までの数列ローマ数字(I、II、III、…)にしたとき、
  5.    最大の長さを持つ文字列を探す関数を書け。
  6.  
  7. 例:
  8. n = 5 のとき、{I、II、III、IV、V}、したがって最大は3。
  9. f(5) = 3
  10. ---------------------------------------------------------------------
  11. wikipedia 'ローマ数字' を参照した
  12. 通常の表現範囲 1..3999までを考慮
  13. 時計の文字盤に使われる IIII は考慮しない
  14. 減算則を使わない方法もあるが考慮しない
  15. 異表記は考慮しない
  16. Unicode や JISの外字では III 等は一文字になるが考慮しない
  17. 同値の解が複数ある場合 ? いずれか一つ? 最小解を一つ? 最大解を一つ? 同値の解全て?
  18.  
  19. 123 -> [1-123] -> 12[0-3], 1[0-1][0-9], 0[0-9][0-9] -> 123, 118, 88 -> 88
  20. 345 -> [1-345] -> 34[0-5], 3[0-3][0-9], [0-2][0-9][0-9] -> 343, 338, 288 -> 338, 288
  21.  
  22. 1887, 2887, 3887 解が 7個
  23. =end
  24.  
  25.  
  26. NumLen = [0,1,2,3,2,1,2,3,4,2]
  27. $numMax = []
  28. 10.times{|n|
  29. mx = NumLen[0..n].max
  30. wrk = []
  31. 0.upto(n){|x|
  32. wrk << x if NumLen[x] == mx
  33. }
  34. $numMax << wrk
  35. }
  36.  
  37. def romeLen( str )
  38. str.chars.map{|x| NumLen[x.to_i] }.inject(:+)
  39. end
  40.  
  41. def f( num )
  42. unless num >= 1 && num <= 3999
  43. warn "Illegal numger #{num}."
  44. exit
  45. end
  46.  
  47. candidate = []
  48. sNum = num.to_s(10)
  49. sNum.chars.map{|x| x.to_i}.reverse.each_with_index{|n,idx|
  50. n -= 1 if idx != 0 && n > 0
  51. $numMax[n].each{|x|
  52. sNum[-1-idx] = x.to_s
  53. str = sNum.sub( /^0+/, '' )
  54. candidate << [ romeLen( str ), str ]
  55. }
  56. sNum[-1-idx] = '8' # [0-9]1桁の最大長
  57. }
  58. candidate.uniq!
  59.  
  60. maxSize = candidate.max_by{|x| x[0]}[0]
  61. candidate.delete_if{|x| x[0] != maxSize }
  62. candidate.map{|x| x[1].to_i }.sort
  63. end
  64.  
  65. #####################################################################
  66.  
  67. def tst( num )
  68. print " #{'%5d' % num} : ", f(num).join(', '), "\n"
  69. end
  70.  
  71. tst(1)
  72. tst(2)
  73. tst(3)
  74. tst(4)
  75. tst(5) #=> 3
  76. tst(6)
  77. tst(7)
  78. tst(8)
  79. tst(9)
  80. tst(10)
  81. tst(11)
  82. tst(12)
  83. tst(13)
  84. tst(17)
  85. tst(27)
  86. tst(87)
  87. tst(887)
  88. tst(1887)
  89.  
Success #stdin #stdout 0.01s 6052KB
stdin
Standard input is empty
stdout
     1 : 1
     2 : 2
     3 : 3
     4 : 3
     5 : 3
     6 : 3
     7 : 3, 7
     8 : 8
     9 : 8
    10 : 8
    11 : 8
    12 : 8
    13 : 8, 13
    17 : 8, 13, 17
    27 : 18, 23, 27
    87 : 38, 78, 83, 87
   887 : 388, 788, 838, 878, 883, 887
  1887 : 888, 1388, 1788, 1838, 1878, 1883, 1887