首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Euler项目17

Euler项目17
EN

Stack Overflow用户
提问于 2012-09-28 20:53:19
回答 1查看 2.8K关注 0票数 3

我一直试图解决欧拉17,并遇到了一些麻烦。这个问题的定义是:

如果数字1到5是用单词写出的:1、2、3、4、5,那么总共使用3+3+5+4+4=19个字母。 如果从1到1000 (包括1000)的所有数字都是用文字写出来的,那么将使用多少个字母? 注意:不要计算空格或连字符。例如,342 (342)包含23个字母,115 (115)包含20个字母。在写出数字时使用"and“是符合英国用法的。

我用Python编写了它,即使看了三四遍代码,我仍然看不出问题的所在。它很长(我刚开始学习python,以前从未编码过),但我基本上只是定义了不同的函数,它们接受不同的数字,并计算每个函数中的字母数。最后我得到了21254,看起来实际的答案是21124,所以我的答案正好是130个。任何帮助都将不胜感激。

代码语言:javascript
复制
# 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
EN

回答 1

Stack Overflow用户

发布于 2012-09-28 20:57:05

解释差异

您的代码中充斥着错误:

  1. 这是错误的: maps60 =6 对错误的贡献:+100 (因为它影响到60到69、160至169、.、960至969)。
  2. 几个青少年错了:青少年(12)7 >>>青少年(13)9 >>>青少年(15)8 >>>青少年(18)9 对错误的贡献:+40 (因为它影响到12、13、.、112、113、.、918)
  3. 和任意数量的表单x10:three_digit(110) 17 对错误的贡献:9(因为110、210、. 910)
  4. 不计算数字20 (考虑i < 20i > 20,而不考虑i == 20)。 对错误的贡献:−6
  5. 数字1000是用英语写成的“一千”,但是:千(1000)8 对错误的贡献:−3
  6. 最后减去10,以弥补其中一个错误。 对错误的贡献:−10

总误差: 100 + 40 +9−6−3−10 = 130.

你怎么能避免这些错误

通过尝试直接使用字母计数,你真的很难检查你自己的工作。“110”里又有几个字母?是17还是16?如果您采用这样的策略,那么测试您的工作就会容易得多:

代码语言:javascript
复制
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))

使用这种方法可以更容易地检查结果:

代码语言:javascript
复制
>>> english(967)
'nine hundred and sixty-seven'
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12647254

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档