1
|
|
|
""" |
2
|
|
|
Project Euler Problem 22: Names Scores |
3
|
|
|
====================================== |
4
|
|
|
|
5
|
|
|
.. module:: solutions.problem22 |
6
|
|
|
:synopsis: My solution to problem #22. |
7
|
|
|
|
8
|
|
|
The source code for this problem can be |
9
|
|
|
`found here <https://bitbucket.org/nekedome/project-euler/src/master/solutions/problem22.py>`_. |
10
|
|
|
|
11
|
|
|
Problem Statement |
12
|
|
|
################# |
13
|
|
|
|
14
|
|
|
Using `names.txt <https://projecteuler.net/project/resources/p022_names.txt>`_ |
15
|
|
|
(right click and 'Save Link/Target As...'), a :math:`46` KB text file containing over five-thousand first names, begin |
|
|
|
|
16
|
|
|
by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its |
|
|
|
|
17
|
|
|
alphabetical position in the list to obtain a name score. |
18
|
|
|
|
19
|
|
|
For example, when the list is sorted into alphabetical order, ``COLIN``, which is worth |
20
|
|
|
:math:`3 + 15 + 12 + 9 + 14 = 53`, is the :math:`938^{th}` name in the list. So, ``COLIN`` would obtain a score of |
|
|
|
|
21
|
|
|
:math:`938 \\times 53 = 49714`. |
22
|
|
|
|
23
|
|
|
What is the total of all the name scores in the file? |
24
|
|
|
|
25
|
|
|
Solution Discussion |
26
|
|
|
################### |
27
|
|
|
|
28
|
|
|
Nothing clever is needed or used here. Simply load the name, sort them, and compute the required score. |
|
|
|
|
29
|
|
|
|
30
|
|
|
Solution Implementation |
31
|
|
|
####################### |
32
|
|
|
|
33
|
|
|
.. literalinclude:: ../../solutions/problem22.py |
34
|
|
|
:language: python |
35
|
|
|
:lines: 38- |
36
|
|
|
""" |
37
|
|
|
|
38
|
|
|
from lib.util import load_dataset |
39
|
|
|
|
40
|
|
|
|
41
|
|
|
def score(name: str) -> int: |
42
|
|
|
""" Compute the numeric score of `name` by summing the individual letter scores |
43
|
|
|
|
44
|
|
|
The letter scores are defined as: |
45
|
|
|
|
46
|
|
|
.. math:: |
47
|
|
|
|
48
|
|
|
A & \\rightarrow 1 \\\\ |
49
|
|
|
B & \\rightarrow 2 \\\\ |
50
|
|
|
& \\dots \\\\ |
51
|
|
|
Z & \\rightarrow 26 |
52
|
|
|
|
53
|
|
|
:param name: the name to score |
54
|
|
|
:return: the score of `name` |
55
|
|
|
|
56
|
|
|
>>> score("COLIN") |
57
|
|
|
53 # 3 + 15 + 12 + 9 + 14 |
58
|
|
|
""" |
59
|
|
|
|
60
|
|
|
scores = {chr(i): i - ord('A') + 1 for i in range(ord('A'), ord('Z') + 1)} |
61
|
|
|
return sum([scores[character] for character in name]) |
62
|
|
|
|
63
|
|
|
|
64
|
|
|
def solve(): |
65
|
|
|
""" Compute the answer to Project Euler's problem #22 """ |
66
|
|
|
names = load_dataset("problems", "p022_names", separator=",") |
67
|
|
|
names = [name.strip("\"") for name in names] # strip quotes off each name |
68
|
|
|
names.sort() # ascending lexicographical order |
69
|
|
|
answer = 0 |
70
|
|
|
for pos, name in enumerate(names): |
71
|
|
|
answer += (pos + 1) * score(name) # one-base the positions within the sorted list |
72
|
|
|
return answer |
73
|
|
|
|
74
|
|
|
|
75
|
|
|
expected_answer = 871198282 |
|
|
|
|
76
|
|
|
|
This check looks for lines that are too long. You can specify the maximum line length.