2016年4月17日日曜日

数字の長さ

Project Euler 17

1 から 5 までを文字で書いてみる。one, two, three, four, five であり、これらの文字数の合計は 3 + 3 + 5 + 4 + 4 = 19 文字になる。
1 から 1000 (one thousand) を文字で書いた場合、どれだけの文字数になるか?

注記: 空白やハイフンは文字数に含めない。例えば 342 (three hundred and fourty-two) の文字数は 23 であり、115 (one hundred and fifteen) は 20 文字である。なお and の利用は英国式に準拠する。


まず指定桁の数を取得する関数 get_digit を以下の通り定義する。
def get_digit(n, c):
    return [int(x) for x in str(n)][c]
また、数値に対応する文字を定義する。
このとき、すべての文字を定義するのではなく、組み合わせで表現できる数を定義する。
c0 = {
  0: "",
  1: "one", 2: "two", 3: "three", 4: "four", 5: "five",
  6: "six", 7: "seven", 8: "eight", 9: "nine", 10: "ten",
  11: "eleven", 12: "twelve", 13: "thirteen", 14: "fourteen", 15: "fifteen",
  16: "sixteen", 17: "seventeen", 18: "eighteen", 19: "nineteen"
  }
c1 = {2: "twenty", 3: "thirty", 4: "forty", 5: "fifty",
      6: "sixty", 7: "seventy", 8: "eighty", 9: "ninety"}
さて、これらを利用して 1 から順番に文字列を生成する。
なお 100 桁の場合、101 や 211 などは、one hundred and one や two hundred and eleven といったように「and」を追加する必要がある。そこで、100 桁の数値の場合、10 桁部の有無により処理を分岐している。
for i in range(1, N+1):
    j = i
    if j >= 1000:
        c = get_digit(j, 0)
        s += c0[c]
        s += "thousand"
        j -= c*1000
        if j == 0:
            continue

    if j >= 100:
        c = get_digit(j, 0)
        s += c0[c]
        s += "hundred"
        j -= c*100
        if j == 0:
            continue
        s += "and"

    if j >= 20:
        c = get_digit(j, 0)
        s += c1[c]
        j -= c*10
        if j == 0:
            continue

    s += c0[j]

0 件のコメント:

コメントを投稿