hp12c
16 February 2012

RubyでText Dollarを解く-CodeEval

なんか想像以上に手こずったよ^ ^;

case式内が見苦しい..

もっと簡単なやり方あるんだろうな。Integer#dollarizeを定義してみた。

数字を英語のドル表記に変換。

#!/usr/bin/env ruby
class Integer
 def dollarize
 num_set = split_by_unit.map(&:__dollarize__)
 join_with_unit(num_set)
 end
 def split_by_unit(unit=10**3)
 q, r = divmod(unit)
 if q < unit
 [q, r]
 else
 q.split_by_unit(unit) << r
 end
 end
 UNDER_TENS = Hash[[*0..9].zip %w(Zero One Two Three Four Five Six Seven Eight Nine)]
 TEENS = Hash[[*10..19].zip %w(Ten Eleven Twelve Thirteen Fourteen Fifteen Sixteen Seventeen Eighteen Nineteen)]
 TYS = Hash[[*20.step(90,10)].zip %w(Twenty Thirty Forty Fifty Sixty Seventy Eighty Ninety)]
 DIGITS = Hash[[10,100,1000].zip %w(Ten Hundred Thousand)]
 def __dollarize__
 ten_flag = false
 digitaize.map do |n, digit|
 case
 when n.zero? && !ten_flag
 # do_nothing
 when digit == 10
 unless n == 1
 TYS[n*digit]
 else
 ten_flag = true
 nil
 end
 when digit == 1 && ten_flag
 ten_flag = false
 TEENS[10+n]
 else
 "#{UNDER_TENS[n]}#{DIGITS[digit]}"
 end
 end.join
 end
 def digitaize
 ns = split_by_unit(10)
 ns.map.with_index { |n, i| [n, 10**(ns.size-1-i)] }
 end
 private
 def join_with_unit(num_set, seps = %w(Thousand Million))
 return UNDER_TENS[0] if num_set == ['','']
 num_set.reverse.inject do |mem, var|
 sep = seps.shift
 sep = nil if var.empty?
 [var, mem].join(sep)
 end
 end
end
puts ARGF.map { |line| line.to_i.dollarize + 'Dollars' }


Please enable JavaScript to view the comments powered by Disqus. blog comments powered by Disqus
ruby_pack8

100円〜で好評発売中!
M'ELBORNE BOOKS



AltStyle によって変換されたページ (->オリジナル) /