challenge 整数の漢数字表記

キーボードから正の整数を入力すると、それを漢数字で表示するプログラムを作ってください☆ 例えば「1732050807568877」なら「千七百三十二兆 五百八億 七百五十六万 八千八百七十七」といった感じです☆ 「一七三二兆 〇五〇八億 〇七五六万 八八七七」ではダメですよ^^;

このお題は匿名での投稿です。 与えられる整数の範囲は一京未満(10000000000000000未満)としたいと思います。 ご投稿ありがとうございます。

2年前のLL Day&Nightの「キミならどう書く」で、 これ専用のCPANモジュールが作られていたような記憶があるので 勝手にPerlからの挑戦状とみなしておきます(笑)

Posted feedbacks - Ruby

小学校時代、図書室に数の本があって無量大数まで覚えたものだった。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
$KCODE='e'
def under10000(n)
  unit = ["千", "百", "十", ""]
  nums = %w[〇 一 二 三 四 五 六 七 八 九]
  n = format("%04d", n.to_i)
  unless n == '0000'
    (0...4).inject("") {|accm, i|
      case n[i]
      when ?0
        accm
      when ?1
        if i==3
          accm << nums[n[i]-?0] << unit[i]
        else
          accm << unit[i]
        end
      else
        accm << nums[n[i]-?0] << unit[i]
      end
    }
  end
end

def japanese(n)
  return "〇" if n.to_s == '0'
  raise "too large number!" if n.to_s.length > 52
  unit = ["極", "載", "正", "澗", "溝", "穣", "(禾予)", "垓", "京", "兆", "億", "万", ""]
  splitted = n.to_s.reverse.scan(/.{1,4}/).map{|s| s.reverse}.reverse
  splitted.unshift(*([nil]*(unit.length-splitted.length)))
  (0...unit.length).inject("") {|accm, i|
    sub = under10000(splitted[i])
    if sub
      accm << sub << unit[i]
    else
      accm
    end
  }
end

japanese 0                      # => "〇"
japanese 1                      # => "一"
japanese 10                     # => "十"
japanese 1125                   # => "千百二十五"
japanese 1111                   # => "千百十一"
japanese 2204                 # => "二千二百四"
japanese 1234567890 # => "十二億三千四百五十六万七千八百九十"
japanese 1732050807568877       # => "千七百三十二兆五百八億七百五十六万八千八百七十七"
japanese 1732050807568877193747198374282342374230983482393942 # => "千七百三十二極五百八載七百五十六正八千八百七十七澗千九百三十七溝四千七百十九穣八千三百七十四(禾予)二千八百二十三垓四千二百三十七京四千二百三十兆九千八百三十四億八千二百三十九万三千九百四十二"
japanese 1000000000000000000000000000000000000000000000000000 # => "千極"
japanese "1000000000000000000000000000000000000000000000000000" # => "千極"
japanese 1000000000200000000000000300000000400000000050054001 # => "千極二十正三百(禾予)四十京五千五万四千一"

るびきちさんのより短くを目標に考えてみましたが、一行かないませんでした。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/local/bin/ruby

def jsen(ary)
  k1 = ["", "一", "二" ,"三", "四", "五", "六", "七", "八", "九"]
  k10 = ['', "十","百", "千"]
  str, s = "", ary.size - 1
  ary.each{|num|
    keta = s
    case num
    when 0
      keta = nil
    when 1
      num = nil unless keta == 0
    end
    str << k1[num].to_s unless num.nil?
    str << k10[keta].to_s unless keta.nil?
    s -= 1
  }
  return str
end

def jnum(n)
  return "零" if n == 0
  str, h, ary = "", Hash.new, Array.new
  k = ["", "万", "億", "兆", "京"]
  key, value = n.to_s.split(//).size - 1, n.to_s.split(//)
  return nil if key > 19 # max "京"
  value.each{|i|
    ary.push i.to_i
    if key.divmod(4)[1] == 0
      h[key.divmod(4)[0]] = ary
      ary = []
    end
    key -= 1
  }
  h.sort.reverse.each{|x, ary|
    str << jsen(ary).to_s 
    str << k[x].to_s + " " unless ary == [0, 0, 0, 0]
  }
  return str
end
#n = 1732050807568877
# 千七百三十二兆 五百八億 七百五十六万 八千八百七十七
n =  0
# => 零
n =  1
# => 一
n = 10
# => 十
n = 100
# => 百
n= 1000
# => 千
n= 10001000
# => 千万 千

print jnum(n)

Index

Feed

Other

Link

Pathtraq

loading...