数をひらがなや漢字にする

小江戸らぐでやってるrails勉強会で一緒に講師側やってる人が
NabeAtzz問題解きましょうって課題を出してたので、といてみた。
* 1〜100の数字を1行ずつ出力
* ただし、3の倍数はひらがなで出力する

class Fixnum
  NUM = ['','いち','','さん','よん','','ろく','なな','はち','きゅう']
  def to_hiragana
    ju = self / 10
    ichi = self % 10
    kekka = ""
    kekka += NUM[ju] if ju > 1
    kekka += "じゅう" if ju > 0
    kekka += NUM[ichi]
    return kekka
  end
end

(1..100).each do | idx |
  p idx % 3 == 0 ? idx.to_hiragana : idx
end

juとかichiとかの変数名に絶望。


まあ、ほぼ十数分差で千まで作成できるモジュール作ってた人がいたのです。
なのでこちらは対抗してじょまで表示出来る様作ってみた。

class Fixnum
  HIRA = ['','いち','','さん','よん','','ろく','なな','はち','きゅう']
  HIRA_KETA = ['','じゅう','ひゃく','せん']
  HIRA_SHITA_KETA = ['','まん','おく','ちょう','けい','がい','じょ']
  def to_hiragana
    return 'ぜろ' if self == 0
    kekka = []
    division = 1
    HIRA_SHITA_KETA.each do | shita_keta |
      kekka << shita_keta
      HIRA_KETA.each_with_index do | keta, keta_idx |
        tmp_kekka = ""
        num = ( self / division ) % 10
        tmp_kekka += HIRA[num] if  num > 1 || keta_idx == 0
        tmp_kekka += keta if num > 0
        kekka << tmp_kekka
        division *= 10
        break if division > self
      end
      break if division > self
    end

    return kekka.reverse.join
  end
end

ちなみに、8000.to_hiraganaの結果は"はちせん"。
なんとも間抜けです。


漢字だときれいなんだろうなあ。
って事で漢字版&負数対応版を作ってみた。

class Integer
  def to_hiragana
    to_moji(['','いち','','さん','よん','','ろく','なな','はち','きゅう'],
            ['','じゅう','ひゃく','せん'],
            ['','まん','おく','ちょう','けい','がい','じょ'],
            'ぜろ','まいなす')
  end

  def to_kanji
    to_moji(['','','','','','','','','',''],
            ['','','',''],
            ['','','','','','',''],
            '', 'マイナス')
  end

  def to_abs
    return  self < 0 ? self * -1 : self
  end

private
  def to_moji(nums, ketas, shita_ketas, zero, minus)
    return zero if self == 0
    abs_self = self.to_abs
    kekka = []
    division = 1
    shita_ketas.each do | shita_keta |
      kekka << shita_keta
      ketas.each_with_index do | keta, keta_idx |
        tmp_kekka = ""
        num = ( abs_self / division ) % 10
        tmp_kekka += nums[num] if  num > 1 || keta_idx == 0
        tmp_kekka += keta if num > 0
        kekka << tmp_kekka
        division *= 10
        break if division > abs_self
      end
      break if division > abs_self
    end

    return (self < 0 ? minus : "")  + kekka.reverse.join
  end
end

実行結果は

1
ひらがな:いち
漢字:一
13
ひらがな:じゅうさん
漢字:十三
32
ひらがな:さんじゅうに
漢字:三十二
30
ひらがな:さんじゅう
漢字:三十
102
ひらがな:ひゃくに
漢字:百二
3000
ひらがな:さんせん
漢字:三千
47212
ひらがな:よんまんななせんにひゃくじゅうに
漢字:四万七千二百十二
10000
ひらがな:いちまん
漢字:一万
100000
ひらがな:じゅうまん
漢字:十万
318920
ひらがな:さんじゅういちまんはちせんきゅうひゃくにじゅう
漢字:三十一万八千九百二十
-100
ひらがな:まいなすひゃく
漢字:マイナス百

こんな感じ。