3

Euler 17 を解こうとしていて、いくつかの問題が発生しています。その問題の定義は次のとおりです。

1から5までの数字を1、2、3、4、5と文字で表すと、3+3+5+4+4=19文字になります。

1 から 1000 までのすべての数字を言葉で書き出すと、何文字になりますか?

注: スペースやハイフンは数えないでください。たとえば、342 (三百四十二) には 23 文字、115 (百十五) には 20 文字が含まれます。数字を書き出すときの「and」の使用は、英国の使用法に準拠しています。

私はこれを Python で書きましたが、コードを 3、4 回実行した後でも、何が問題なのかわかりません。長いです (私は Python の学習を始めたばかりで、これまでコーディングしたことはありません) が、基本的には、異なる桁数を取り、それぞれの文字数をカウントするさまざまな関数を定義しただけです。最終的に 21254 になり、実際の答えは 21124 のように見えるので、正確に 130 ずれています。

# create dict mapping numbers to their
# lengths in English

maps = {}
maps[0] = 0
maps[1] = 3
maps[2] = 3
maps[3] = 5
maps[4] = 4
maps[5] = 4
maps[6] = 3
maps[7] = 5
maps[8] = 5
maps[9] = 4
maps[10] = 3
maps[11] = 6
maps['and'] = 3
maps['teen'] = 4
maps[20] = 6
maps[30] = 6
maps[40] = 5
maps[50] = 5
maps[60] = 6
maps[70] = 7
maps[80] = 6
maps[90] = 6
maps[100] = 7
maps[1000] = 8

# create a list of numbers 1-1000
def int_to_list(number):
    s = str(number)
    c = []
    for digit in s:
        a = int(digit)
        c.append(a)
    return c  # turn a number into a list of its digits
def list_to_int(numList):
    s = map(str, numList)
    s = ''.join(s)
    s = int(s)
    return s


L = []
for i in range(1,1001,1):
    L.append(i)

def one_digit(n):
    q = maps[n]
    return q
def eleven(n):
    q = maps[11]
    return q
def teen(n):
    digits = int_to_list(n) 
    q = maps[digits[1]] + maps['teen']
    return q
def two_digit(n):
    digits = int_to_list(n)
    first = digits[0]
    first = first*10
    second = digits[1]
    q = maps[first] + one_digit(second)
    return q
def three_digit(n):
    digits = int_to_list(n)
    first = digits[0]
    second = digits[1]
    third = digits[2]

    # first digit length
    f = maps[first]+maps[100]

    if second == 1 and third == 1:
        s = maps['and'] + maps[11]
    elif second == 1 and third != 1:
        s = digits[1:]
        s = list_to_int(s)
        s = maps['and'] + teen(s)
    elif second == 0 and third == 0:
        s = maps[0]
    elif second == 0 and third != 0:
        s = maps['and'] + maps[third]
    else:
        s = digits[1:]
        s = list_to_int(s)
        s = maps['and'] + two_digit(s)

    q = f + s
    return q
def thousand(n):
    q = maps[1000]
    return q

# generate a list of all the lengths of numbers

lengths = []


for i in L:
    if i < 11:
        n = one_digit(i)
        lengths.append(n)
    elif i == 11:
        n = eleven(i)
        lengths.append(n)
    elif i > 11 and i < 20:
        n = teen(i)
        lengths.append(n)
    elif i > 20 and i < 100:
        n = two_digit(i)
        lengths.append(n)
    elif i >= 100 and i < 1000:
        n = three_digit(i)
        lengths.append(n)
    elif i == 1000:
        n = thousand(i)
        lengths.append(n)
    else:
        pass

# since "eighteen" has eight letters (not 9), subtract 10
sum = sum(lengths) - 10
print "Your number is: ", sum
4

1 に答える 1

9

不一致の説明

あなたのコードはエラーだらけです:

  1. これは間違っています:

    maps[60] = 6
    

    エラーの原因:+100(60から69、160から169、...、960から969に影響するため)。

  2. 何人かのティーンエイジャーは間違っています:

    >>> teen(12)
    7
    >>> teen(13)
    9
    >>> teen(15)
    8
    >>> teen(18)
    9
    

    エラーの原因:+40(12、13、...、112、113、...、918に影響するため)

  3. そして、x10の形式の任意の数:

    >>> three_digit(110)
    17
    

    エラーの原因:9(110、210、... 910のため)

  4. 数20はカウントされません(あなたは考慮i < 20しますが、カウントしi > 20ませんi == 20)。

    エラーの原因:-6

  5. 数字の1000は英語で「1000」と書かれていますが:

    >>> thousand(1000)
    8
    

    エラーの原因:-3

  6. これらのエラーの1つを補正するために、最後に10を引きます。

    エラーの原因:-10

合計エラー:100 + 40 + 9 − 6 − 3 − 10=130。

これらの間違いをどのように回避できたでしょうか

文字数を直接操作しようとすると、自分の作業を確認するのが非常に難しくなりました。「百十」にはまた何文字ありますか?17ですか、それとも16ですか。次のような戦略を採用していれば、作業をテストするのははるかに簡単でした。

unit_names = """zero one two three four five six seven eight nine ten
                eleven twelve thirteen fourteen fifteen sixteen seventeen
                eighteen nineteen""".split()
tens_names = """zero ten twenty thirty forty fifty sixty seventy eighty
                ninety""".split()

def english(n):
    "Return the English name for n, from 0 to 999999."
    if n >= 1000:
        thous = english(n // 1000) + " thousand"
        n = n % 1000
        if n == 0:
            return thous
        elif n < 100:
            return thous + " and " + english(n)
        else:
            return thous + ", " + english(n)
    elif n >= 100:
        huns = unit_names[n // 100] + " hundred"
        n = n % 100
        if n == 0:
            return huns
        else:
            return huns + " and " + english(n)
    elif n >= 20:
        tens = tens_names[n // 10]
        n = n % 10
        if n == 0:
            return tens
        else:
            return tens + "-" + english(n)
    else:
        return unit_names[n]

def letter_count(s):
    "Return the number of letters in the string s."
    import re
    return len(re.findall(r'[a-zA-Z]', s))

def euler17():
    return sum(letter_count(english(i)) for i in range(1, 1001))

このアプローチを使用すると、結果を確認するのが簡単になります。

>>> english(967)
'nine hundred and sixty-seven'
于 2012-09-28T20:57:05.520 に答える