Вопрос по python – Проект Euler # 22 Python, 2205 очков отсутствуют?

2

Я работаю над проблемой 22 проекта Эйлера:

Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.

For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 × 53 = 49714.

What is the total of all the name scores in the file?

http://projecteuler.net/problem=22

Когда я компилирую код ниже, я получаю ответ871196077, Правильный ответ должен быть871198282.

import time

def euler_22():

<code>## Creates a sorted list of the names in Py_Euler_22.txt
names = open('Py_Euler_22.txt', 'r')
names = names.read()
names = names.split('","')
names[0] = names[0][1:]
names[-1] = names[-1][:-2]
names = sorted(names)

## Creates a dictionary: letter -> value
value_letters = {}
start = ord("A")
for i in range(0, 26):
    value_letters[chr(start+i)] = i+1

result = 0

for i in range(1, len(names)+1):
    name = names[i-1] 
    sum_letters = 0
    for letter in name:
        sum_letters += value_letters[letter]*i 
        # = value of the letter multiplied with the name position
    result += sum_letters
return result
</code>

tstart = time.time() print euler_22() print "Run time: " + str(time.time() - tstart)

Я пытался найти программу с похожим решением, но я знаю только Python, который ограничивает возможности. Я запустил программу с более простыми текстовыми файлами, которые я создал, где я могу получить ответ без программы, и все они работали. Я гуглил ответ на проблему, но это тоже не помогло, так как я не могу найти недостающие точки.

Я новичок, поэтому буду очень признателен за любые советы, касающиеся программы и Python, а не только те, которые помогут мне правильно решить проблему.

Большое спасибо!

@AdamMatan, вам нужно использовать имена [-1] [: - 1], чтобы удалить кавычку с фамилией. spinlok
почему этоnames[0] = names[0][1:] names[-1] = names[-1][:-2] ?? Vineet Menon
Вы абсолютно правы. Adam Matan
Удалить кавычки из имени и фамилии; Я думаю, что разделение на, и раздеться" для каждого имени будет лучше, но его код будет работать. Adam Matan

Ваш Ответ

3   ответа
3

Вотqnames отсортированный список имен, которые создает ваш код, иsorted_names это мое:

>>> for a,b in zip(qnames, sorted_names):
...     if a != b:
...         print a, b
... 
ALONS ALONSO

Для удовольствия: однострочник - вложенный список, avast ye!

print sum ( [ (pos+1) * nv for pos, nv in enumerate([ sum ( [ ord(char) - 64 for char in name ] ) for name in sorted([name.strip('"') for name in open('names.txt','r').readline().split(",")]) ]) ] )

Или более наглядно:

print sum (
    [(pos+1) * nv for pos, nv in
        enumerate([ sum ([ ord(char) - 64 for char in name ] ) for name in
            sorted([name.strip('"') for name in
                open('names.txt','r').readline().split(",")]) ]) ] )

Черная магия в том, что ASCIIA целое число65, ASCIIB целое число66и так далее - такord(char) - 64 возвращает вам «значение буквы» изchar.

Изменить 2:

Полное, понятное человеку решение, которое я втиснул в одну строку для вашего удовольствия.

with open('names.txt','r') as f:
    data = f.readline();

names = [name.strip('"') for name in data.split(",")]
sorted_names = sorted(names)
name_values = [ sum ( [ ord(char) - 64 for char in name ] ) for name in sorted_names ]
name_position_values = [ (pos+1) * nv for pos, nv in enumerate(name_values) ]
total_sum = sum(name_position_values)

# debug output
from pprint import pprint
#position, word value, position * word value, word
pprint(zip(xrange(1,len(names)+1),name_values,name_position_values,sorted_names))

Обратите внимание на интенсивное использование списочных представлений[x for x in list_of_xes] вместо петель, аsum() функция вместоfor x in xes: sum += x.

Здесь есть и другие хитрости, но урок, который нужно взять с собой, заключается в том, что списки и функции, которые обрабатывают списки, могут сделать ваш код намного проще и проще для чтения.

Изменить 3:

pprint.pprint() функция довольноprint()& Quot ;. Это отлично подходит для отладки.

Изменить 4:

Кодовая версия для гольфа (142 символа):

print sum([(p+1)*v for p,v in enumerate([sum(map(ord,n))-64*len(n) for n in sorted([n[1:-1] for n in open('names.txt').read().split(",")])])])
Error: User Rate Limit Exceeded J.S.
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded J.S.
Error: User Rate Limit ExceededOh, and kids: Don't try this at home.)
1

и похоже, что вы случайно обрезали последний символ последнего слова. Чтобы убрать цитаты из последнего слова, используйте:

names[-1] = names[-1][:-1]
0

когда вы преобразуете содержимое файла в список, удалите их, когда вы обрабатываете список.

# Project Euler Problem 22
# Name Scores

def score(name):
    total = 0

    for char in name:
        total += (ord(char) - 64) # scale so A = 1, B = 2...

    return total

def main():
    # Open the names file for reading
    infile = open('names.txt', 'r')

    # Read the entire contents of the file
    file_contents = infile.read()

    # Close the file
    infile.close()

    # Convert file contents to a list of quoted names and sort them
    list_of_names = file_contents.split(',')
    list_of_names.sort()

    position = 1
    total = 0
    for name in list_of_names:
        name = name.strip('"') # strip the quotes from names individually
        total += score(name) * position
        position += 1

    print(total)

if __name__ == "__main__":
    main()

Похожие вопросы