Hatena::Grouprubyist

うんたらかんたらRuby RSSフィード

2008-11-09re:数字を英語発音にする

re:数字を英語発音にする

| 22:38 | re:数字を英語発音にする - うんたらかんたらRuby を含むブックマーク はてなブックマーク - re:数字を英語発音にする - うんたらかんたらRuby

面白そうなのでやってみた。

Ruby写経+練習問題を解く - krystal: プログラミング超初心者(文系) - Rubyist


ソース

def num_in_english(number)
  print "#{number}  "
  
  if number < 0
    return "負でない数を入力してください。"
  end
  if number == 0
    return "zero"
  end
  
  output = []
  mod = number  # 初期値
  
  $ones_place = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
  $tens_place = ["ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"]
  $teenagers = ["eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
  bignums = [[1e6, "millon"], [1e3, "thousand"]]


  # 1000以上を変換
  if number >= 100
    bignums. each do |bignum|
      div, mod = mod.divmod(bignum[0])
      if div >= 100
        output << num_in_english_under1000(div) << bignum[1]
      elsif div >= 10
        output << num_in_english_under100(div) << bignum[1]
      elsif div > 0
        output << $ones_place[div - 1] << bignum[1]
      end
    end
  end
  
  if mod > 0
    output << num_in_english_under1000(mod)
  end
  output.join(" ")
end

# 100以上1000未満を変換
def num_in_english_under1000(mod)
  output = []
  div, mod = mod.divmod(100)

  if div > 0
    output << $ones_place[div - 1]
    output << "hundred"
    if mod > 0
      output << num_in_english_under100(mod)
    end
  else
    #100未満
    output << num_in_english_under100(mod)
  end  
  output.join(" ")
end

# 100未満を変換
def num_in_english_under100(mod)
  output = []
  # 10以上99以下を変換
  if mod >= 10
    div, mod = mod.divmod(10)
    if div > 0
      if div ==1 && mod > 0
        #11以上19以下
        output << $teenagers[mod -1]
        return output
      else
        #10、20以上99以下
        output << $tens_place[div -1]
      end
    end
  end
  
  # 1以上9以下を変換
  if mod > 0
    output << $ones_place[mod -1]
  end
  output.join(" ")
end


puts num_in_english(0)
puts num_in_english(7)
puts num_in_english(11)
puts num_in_english(16)
puts num_in_english(34)
puts num_in_english(56)
puts num_in_english(88)
puts num_in_english(99)
puts num_in_english(100)
puts num_in_english(101)
puts num_in_english(234)
puts num_in_english(4634)
puts num_in_english(8888)
puts num_in_english(6000000)
puts num_in_english(7000321)
puts num_in_english(7654321)
puts num_in_english(87654321)

結果

0 zero

7 seven

11 eleven

16 sixteen

34 thirty four

56 fifty six

88 eighty eight

99 ninety nine

100 one hundred

101 one hundred one

234 two hundred thirty four

4634 four thousand six hundred thirty four

8888 eight thousand eight hundred eighty eight

6000000 six millon

7000321 seven millon three hundred twenty one

7654321 seven millon six hundred fifty four thousand three hundred twenty one

87654321 eighty seven millon six hundred fifty four thousand three hundred twenty one


とりあえず

  1. divmodで商と余りがとれるよ
  2. 文字列連結は<<の方が+より早いらしいよ 参考: 文字列の連結 - ぞえ の戯れ言
  3. 空白入れるのは、配列のjoinすると楽だよ

他は汚いので参考程度に。もう少しきれいにしたいけど時間切れ。

krystalkrystal2008/11/11 15:43 * なるほどですね、divmodのほうが理解しやすいですね。基処のテストによく出てきますが、実際使ったことありません。
* 連結では「+」より「<<」のほうが早いのは初めて知りました!
* joinの練習もやったことありますが、これも応用できてませんね。

私が書いたベースは汚くて申し訳ないです。
またコメントやアドバイスをいただけると嬉しいです^^
これからもよろしくお願い致します。

rochefortrochefort2008/11/11 23:18私も経験浅いので、ここで徐々に勉強できたらと思います。
こちらこそよろしく。

トラックバック - http://rubyist.g.hatena.ne.jp/rochefort/20081109