金額を漢字フォーマット
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/47175
ruby-listでこういうメールが飛んでいて、ちょっとやってみようかと思った。EmacsLispで。
まず
12345678912345
↑こんな数字があったとして、
(12345678912345)
リストにして
(1234567891 2345)
(123456 7891 2345)
(12 3456 7891 2345)
こういうふうに、4桁ずつ分けて、あとから単位つければいいんじゃないかなと思った。
つまり、
carが10000より大きいか調べる
大きければ10000で割り、商と余りとcdrをくっつけた新しいリストを返す
小さければそのままのリストを返す
を再帰的に行う。
(defun div-by-10000 (money-list) (let* ((money (car money-list)) (larger-than-10000-p (> money 10000))) (cond (larger-than-10000-p (div-by-10000 (append (list (/ money 10000) (% money 10000)) (cdr money-list)))) (t money-list))))
で、次は得られた↓このリストをフォーマットする
(12 3456 7891 2345)
それには
("円" "万" "億" "兆" "京" "垓" "抒" "穣" "溝" "澗" "正" "載" "極" "恒河沙" "阿僧祇" "那由他" "不可思議" "無量大数")
こういうリストを用意して、mapする。
(let* ((money-list (list money)) (units '("円" "万" "億" "兆" "京" "垓" "抒" "穣" "溝" "澗" "正" "載" "極" "恒河沙" "阿僧祇" "那由他" "不可思議" "無量大数"))) (map 'list #'concat (reverse (map 'list #'number-to-string (div-by-10000 money-list))) units))
で、あとは
("2345円" "7891万" "3456億" "12兆")
これをひっくり返してつなげればよろし。
reduceを使うと便利。
全貌
(defun div-by-10000 (money-list) (let* ((money (car money-list)) (larger-than-10000-p (> money 10000))) (cond (larger-than-10000-p (div-by-10000 (append (list (/ money 10000) (% money 10000)) (cdr money-list)))) (t money-list)))) (defun format-money (money) (let* ((money-list (list money)) (units '("円" "万" "億" "兆" "京" "垓" "抒" "穣" "溝" "澗" "正" "載" "極" "恒河沙" "阿僧祇" "那由他" "不可思議" "無量大数")) (money-list (map 'list #'concat (reverse (map 'list #'number-to-string (div-by-10000 money-list))) units))) (reduce #'concat (reverse money-list ))))
(format-money 12345678912345)
=> "12兆3456億7891万2345円"
ナユタ、フカシギくらいでっかい数やろうとするとoverflowエラーなってしまうw
2010/07/19 追記
Rubyでの例を見っけ
億とか京とか - しょんぼり技術メモ
http://d.hatena.ne.jp/syonbori_tech/20100623/1277299525