All Euler problems
Project Euler

Exploring Strings for Which Only One Character Comes Lexicographically After Its Neighbour to the Left

Taking three different letters from the 26 letters of the alphabet, characters strings of length 3 can be formed. For each length n where 1 <= n <= 26, let p(n) be the number of strings of length n...

Source sync Apr 19, 2026
Problem #0158
Level Level 07
Solved By 4,204
Languages C++, Python
Answer 409511334375
Length 263 words
graphsequencebrute_force

Problem Statement

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

Taking three different letters from the \(26\) letters of the alphabet, character strings of length three can be formed.

Examples are ’abc’, ’hat’ and ’zyx’.

When we study these three examples we see that for ’abc’ two characters come lexicographically after its neighbour to the left.

For ’hat’ there is exactly one character that comes lexicographically after its neighbour to the left. For ’zyx’ there are zero characters that come lexicographically after its neighbour to the left.

In all there are \(10400\) strings of length \(3\) for which exactly one character comes lexicographically after its neighbour to the left.

We now consider strings of \(n \le 26\) different characters from the alphabet.

For every \(n\), \(p(n)\) is the number of strings of length \(n\) for which exactly one character comes lexicographically after its neighbour to the left.

What is the maximum value of \(p(n)\)?

Problem 158: Exploring Strings for Which Only One Character Comes Lexicographically After Its Neighbour to the Left

Mathematical Analysis

Setup

We choose nn distinct letters from 26, then arrange them in a sequence of length nn such that exactly one position ii (2in2 \le i \le n) satisfies si>si1s_i > s_{i-1} (an “ascent”).

Counting with Eulerian numbers

The number of permutations of nn elements with exactly kk ascents is the Eulerian number nk\langle {n \atop k} \rangle.

The Eulerian numbers satisfy:

nk=(k+1)n1k+(nk)n1k1\left\langle {n \atop k} \right\rangle = (k+1)\left\langle {n-1 \atop k} \right\rangle + (n-k)\left\langle {n-1 \atop k-1} \right\rangle

with 00=1\langle {0 \atop 0} \rangle = 1.

We want exactly 1 ascent, so we need n1\langle {n \atop 1} \rangle.

Formula for one ascent

The Eulerian number for exactly one ascent is:

n1=2nn1\left\langle {n \atop 1} \right\rangle = 2^n - n - 1

Proof by induction: Base case 21=1=421\langle {2 \atop 1} \rangle = 1 = 4 - 2 - 1. Inductive step:

n1=2n11+(n1)n10=2(2n1n)+(n1)=2n2n+n1=2nn1\langle {n \atop 1} \rangle = 2\langle {n-1 \atop 1} \rangle + (n-1)\langle {n-1 \atop 0} \rangle = 2(2^{n-1} - n) + (n-1) = 2^n - 2n + n - 1 = 2^n - n - 1

Choosing the letters

Since we choose nn letters from 26, and the relative order is determined by the permutation:

p(n)=(26n)n1=(26n)(2nn1)p(n) = \binom{26}{n} \cdot \left\langle {n \atop 1} \right\rangle = \binom{26}{n}(2^n - n - 1)

Maximizing p(n)p(n)

We compute p(n)p(n) for each nn from 1 to 26 and find the maximum. Note:

  • p(1)=0p(1) = 0 (no pair to compare)
  • p(2)=(262)1=325p(2) = \binom{26}{2} \cdot 1 = 325
  • The maximum occurs at some intermediate value of nn.

Computing shows p(n)p(n) is maximized at n=18n = 18 with:

p(18)=(2618)(21819)=1562275×262125=409511334375p(18) = \binom{26}{18}(2^{18} - 19) = 1562275 \times 262125 = 409511334375

Correctness

Theorem. The method described above computes exactly the quantity requested in the problem statement.

Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer. \square

Complexity

O(26)O(26) to compute all values.

Answer

409511334375\boxed{409511334375}

Code

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

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

typedef long long ll;
typedef __int128 lll;

int main() {
    // Compute C(26, n) * (2^n - n - 1) for n = 1..26, find max
    // Use __int128 to avoid overflow in intermediate computation

    // Precompute C(26, n)
    ll C[27];
    C[0] = 1;
    for (int i = 1; i <= 26; i++) {
        C[i] = C[i-1] * (27 - i) / i;
    }

    ll best = 0;
    for (int n = 1; n <= 26; n++) {
        ll euler1 = (1LL << n) - n - 1; // 2^n - n - 1
        ll pn = C[n] * euler1;
        best = max(best, pn);
    }

    cout << best << endl;
    return 0;
}