我一直在尝试解决欧拉 17 问题,但遇到了一些麻烦。该问题的定义是:
如果数字 1 到 5 用单词写成:一、二、三、四、五,那么总共使用了 3 + 3 + 5 + 4 + 4 = 19 个字母。
如果从 1 到 1000(一千)的所有数字都用文字写出来,需要使用多少个字母?
注意:不要计算空格或连字符。例如,342(三百四十二)包含 23 个字母,115(一百一十五)包含 20 个字母。写数字时使用“and”符合英国习惯。
我用Python写的,代码看了三四遍还是看不出问题出在哪里。它很长(我刚刚开始学习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
解释差异
您的代码充满了错误:
-
这是错误的:
maps[60] = 6
对错误的贡献:+100(因为它影响 60 到 69、160 到 169、...、960 到 969)。
-
很多青少年都犯了这样的错误:
>>> teen(12)
7
>>> teen(13)
9
>>> teen(15)
8
>>> teen(18)
9
错误贡献:+40(因为它影响 12、13、...、112、113、...、918)
-
以及任何 x10 形式的数字:
>>> three_digit(110)
17
错误贡献:9(因为 110、210、... 910)
-
数字 20 不算在内(你考虑i < 20
and i > 20
但不是i == 20
).
对错误的贡献:−6
-
数字 1000 在英语中写为“一千”,但是:
>>> thousand(1000)
8
对错误的贡献:−3
-
最后减去 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'
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)