我正在努力解决Project Euler上的Problem 22:
使用
names.txt
(右键单击并将“保存链接/目标为...”),46K文本 包含超过五千个名字的文件,首先对其进行排序 按字母顺序排列。然后计算出字母值 每个名称,将该值乘以其中的字母位置 列表以获得名称分数。例如,当列表按字母顺序排序时,COLIN, 值得3 + 15 + 12 + 9 + 14 = 53,是第938名 名单。因此,COLIN将获得938×53 = 49714的分数。
文件中所有名称分数的总和是多少?
names.txt
的内容是
"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER","MARIA",....[46k omitted]
我不明白为什么在使用此代码时我得到的答案不正确:
import os
chart=open('names.txt')
doc=chart.read()
doc=doc.split(',')
doc.sort()
z=0
def nameNum(name):
r=0
for letter in name:
r=r+ord(letter) - 64
return r
for string in doc:
z+=(doc.index(string)+1)*nameNum(string)
print z
我试图让z产生答案,但它不正确,我无法弄清楚原因。
顺便说一下,这是python 3。
答案 0 :(得分:3)
您正在为引号"
和名称进行评分。最简单的方法是在以逗号分割之前删除它们;
...
doc=chart.read()
doc=doc.replace('"', '')
doc=doc.split(',')
...
在修复之前,你获得了COLIN的负分
Name: "COLIN", pos: 938, score: -6566
...但是根据示例修复后它是正确的;
Name: COLIN, pos: 938, score: 49714
答案 1 :(得分:1)
您的实际算法没有任何问题,但问题是当您按,
分割文件时,每个名称周围仍有"
个字符;因此,您错误地将2 * (64 - ord('"'))
添加到每个名称的分数中,这就是您获得错误结果的原因。
该文件的格式可以通过ast.literal_eval()
轻松解析为字符串元组:
import ast
with open('names.txt') as f:
contents = f.read()
names = sorted(ast.literal_eval(contents))
现在names
是一个排序的名称列表,没有任何额外的字符。使用此列表而不是doc
,我从您的算法中得到了正确的结果。
虽然这不会影响算法本身,但使用.index
查找项目索引的效率非常低:
for string in doc:
z+=(doc.index(string)+1)*nameNum(string)
你应该use enumerate
代替:
for number, name in enumerate(names, start=1):
z += number * nameNum(name)
现在names
是一个排序的名称列表,没有任何额外的字符。通过这些更改,我得到了正确的结果。