"漢数字からアラビア数字"をschemeで
やりたいのは単純で、一〜五十くらいまでで、十一とか三十一とかの表記となる。これを1〜50、11とか31とかに直す。
L'eclat des jours(2010-12-09)
なんとなくGaucheでチャレンジ。
(define (kj_to_ar kj-string) (define kj-number '((#\十 10) (#\一 1) (#\二 2) (#\三 3) (#\四 4) (#\五 5) (#\六 6) (#\七 7)(#\八 8) (#\九 9))) (define (kj-ref kj) (cadr (assoc kj kj-number))) (define base-char #\十) (define (base-char? kj) (char=? kj base-char)) (let ((r-kj-lis (reverse (string->list kj-string)))) (define (iter rest base result) (if (null? rest) result (if base (iter (cdr rest) base (+ result (* (- (kj-ref (car rest)) 1) (kj-ref base-char)))) (iter (cdr rest) (base-char? (car rest)) (+ result (kj-ref (car rest))))))) (iter r-kj-lis #f 0)))
実行
gosh> (kj_to_ar "一") 1 gosh> (kj_to_ar "五") 5 gosh> (kj_to_ar "十三") 13 gosh> (kj_to_ar "十") 10 gosh> (kj_to_ar "二十一") 21
Rubyで実装するとこんな感じかなぁ。って全然変わってるけど。
def kj_to_ar(s) kj_list = '零一二三四五六七八九十' s.reverse! base = 10 base_ex = false result = 0 s.each_char do |c| if base_ex result += (kj_list.index(c) - 1) * base elsif kj_list.index(c) == base result += base base_ex = true else result += kj_list.index(c) end end result end
実行
irb(main):163:0> kj_to_ar('十') => 10 irb(main):164:0> kj_to_ar('二十五') => 25 irb(main):165:0> kj_to_ar('十六') => 16 irb(main):166:0> kj_to_ar('六十') => 60 irb(main):167:0> kj_to_ar('七') => 7 irb(main):168:0> kj_to_ar('八') => 8
全然スマートにはならなかったな…。