I'm working on problem 22 of Project Euler:
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
When I compile my code below, I get the answer 871196077. The correct answer should be 871198282.
import time
def euler_22():
## 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
tstart = time.time() print euler_22() print "Run time: " + str(time.time() - tstart)
I tried to find a program with a similar solution, but I only know Python, that limits the options. I ran the program with simpler text-files, I created, where I can get the answer without a program and all of them worked. I googled the answer to the problem, but that didn't help either, since I cant find the missing points.
I'm a beginner, so I would really appreciate any tips regarding the program and Python, not only those, that will help me to solve the problem correctly.
Thanks a lot!
Rather than trying to strip all the quotes from the names at once when you're converting the file contents to a list, strip them when you're processing the list.
I just cross-checked your code, and it looks like you're inadvertently chopping off the last character of the last word. To strip off the quotes from the last word, use:
You have accidentally mangled one name.
Here
qnames
is the sorted list of names your code produces, andsorted_names
is mine:For fun: a one-liner - nested list comprehensions, avast ye!
Or more readably:
The black magic is that ASCII
A
is integer65
, ASCIIB
is integer66
, and so on - soord(char) - 64
gets you the "letter value" ofchar
.Edit 2:
The full, human-readable, solution that I crammed into one line for your amusement.
Note the heavy use of list comprehensions
[x for x in list_of_xes]
instead of loops, and thesum()
function instead offor x in xes: sum += x
.There are some other tricks in here, but the take-home lesson is that list comprehensions and functions that process lists can make your code much simpler and easier to read.
Edit 3:
The
pprint.pprint()
function is a "prettyprint()
". It's great for debugging.Edit 4:
Code golf version (142 chars):