All Euler problems
Project Euler

Names Scores

Given a text file of over five thousand first names, sort the names into lexicographic (alphabetical) order. Define the alphabetical value of a name as the sum of the positional values of its lette...

Source sync Apr 19, 2026
Problem #0022
Level Level 00
Solved By 146,649
Languages C++, Python
Answer 871198282
Length 431 words
sequencebrute_forcelinear_algebra

Problem Statement

This archive keeps the full statement, math, and original media on the page.

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 \(938\)th name in the list. So, COLIN would obtain a score of \(938 \times 53 = 49714\).

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

Problem 22: Names Scores

Mathematical Development

Definitions

Definition 1 (Letter Value). For an uppercase Latin letter cc, define

val(c)=ord(c)64,\operatorname{val}(c) = \operatorname{ord}(c) - 64,

where ord\operatorname{ord} returns the ASCII codepoint. This yields val(A)=1,val(B)=2,,val(Z)=26\operatorname{val}(\texttt{A}) = 1, \operatorname{val}(\texttt{B}) = 2, \ldots, \operatorname{val}(\texttt{Z}) = 26.

Definition 2 (Alphabetical Value). For a name w=c1c2ckw = c_1 c_2 \cdots c_k over the alphabet {A,,Z}\{\texttt{A}, \ldots, \texttt{Z}\}, the alphabetical value is

α(w)=i=1kval(ci).\alpha(w) = \sum_{i=1}^{k} \operatorname{val}(c_i).

Definition 3 (Name Score). Let w1w2wnw_1 \prec w_2 \prec \cdots \prec w_n be the names in lexicographic order. The name score of wjw_j is S(wj)=jα(wj)S(w_j) = j \cdot \alpha(w_j).

Theorems and Proofs

Theorem 1 (Well-Definedness). The total score T=j=1njα(wj)T = \sum_{j=1}^{n} j \cdot \alpha(w_j) is uniquely determined by the input set of names.

Proof. The lexicographic order \preceq on Σ\Sigma^* (finite strings over a totally ordered alphabet Σ\Sigma) is a total order: for strings u,vu, v, compare character-by-character at the first differing position, with shorter strings preceding longer ones if one is a prefix of the other. Since the input names are distinct (an assumption from the problem data), the sorted sequence w1w2wnw_1 \prec w_2 \prec \cdots \prec w_n is unique. Each α(wj)\alpha(w_j) depends only on the string wjw_j, and the index jj depends only on the sorted order. Therefore TT is uniquely determined. \square

Lemma 1 (Bounds on α\alpha). For any name ww of length kk with characters in {A,,Z}\{\texttt{A}, \ldots, \texttt{Z}\},

kα(w)26k.k \leq \alpha(w) \leq 26k.

Proof. Each character contributes at least val(A)=1\operatorname{val}(\texttt{A}) = 1 and at most val(Z)=26\operatorname{val}(\texttt{Z}) = 26 to the sum. The bounds follow by summing over all kk characters. \square

Lemma 2 (ASCII and Dictionary Order). Lexicographic comparison of ASCII-encoded uppercase Latin strings coincides with standard dictionary order.

Proof. The ASCII codes of A,B,,Z\texttt{A}, \texttt{B}, \ldots, \texttt{Z} are 65,66,,9065, 66, \ldots, 90, which is a strictly increasing sequence. Lexicographic order is defined by the order on individual characters, so ASCII byte comparison produces the same total order as alphabetical comparison. \square

Editorial

We read the quoted names, sort them lexicographically, and then evaluate each name score in sorted order. For position jj, we compute the alphabetical value of the name by summing its letter values and multiply by jj before adding to the running total. This is sufficient because the problem definition depends only on the sorted order and those per-name letter sums.

Pseudocode

Algorithm: Total of Name Scores
Require: A finite list of quoted names.
Ensure: The sum of all name scores after lexicographic sorting.
1: Read the names, remove quotation marks, and sort the resulting list lexicographically.
2: Initialize total ← 0.
3: For each position j and corresponding name w in the sorted list, compute value(w) ← sum of the letter positions in w.
4: Update total ← total + j · value(w).
5: Return total.

Complexity Analysis

Proposition. The algorithm runs in O(nLlogn)O(nL \log n) time and O(nL)O(nL) space, where nn is the number of names and LL is the maximum name length.

Proof. Sorting nn strings by comparison-based sort requires O(nlogn)O(n \log n) comparisons, each costing O(L)O(L) character inspections in the worst case, for a total of O(nLlogn)O(nL \log n). The subsequent linear scan computes α(wj)\alpha(w_j) for each name in O(L)O(L) time, contributing O(nL)O(nL) total, which is dominated by the sorting step. Storage for all nn names of length at most LL requires O(nL)O(nL) space. \square

Answer

871198282\boxed{871198282}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_022/solution.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    ifstream fin("names.txt");
    if (!fin.is_open()) {
        cerr << "Error: names.txt not found." << endl;
        return 1;
    }

    string content((istreambuf_iterator<char>(fin)), istreambuf_iterator<char>());
    fin.close();

    vector<string> names;
    string cur;
    bool in_quote = false;
    for (char c : content) {
        if (c == '"') {
            in_quote = !in_quote;
            if (!in_quote && !cur.empty()) {
                names.push_back(cur);
                cur.clear();
            }
        } else if (in_quote) {
            cur += c;
        }
    }

    sort(names.begin(), names.end());

    long long total = 0;
    for (int i = 0; i < (int)names.size(); i++) {
        int alpha = 0;
        for (char c : names[i])
            alpha += c - 'A' + 1;
        total += (long long)(i + 1) * alpha;
    }

    cout << total << endl;
    return 0;
}