All Euler problems
Project Euler

Prize Strings

A particular school offers cash prizes to children with good attendance and punctuality. If they are absent for three consecutive days or late on more than one day, their prize is forfeited. Over a...

Source sync Apr 19, 2026
Problem #0191
Level Level 05
Solved By 7,988
Languages C++, Python
Answer 1918080160
Length 528 words
sequencebrute_forcelinear_algebra

Problem Statement

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

A particular school offers cash rewards to children with good attendance and punctuality. If they are absent for three consecutive days or late on more than one occasion then they forfeit their prize.

During an n-day period a trinary string is formed for each child consisting of L’s (late), O’s (on time), and A’s (absent).

Although there are eighty-one trinary strings for a 4-day period that can be formed, exactly forty-three strings would lead to a prize:

OOOO OOOA OOOL OOAO OOAA OOAL OOLO OOLA OAOO OAOA
OAOL OAAO OAAL OALO OALA OLOO OLOA OLAO OLAA AOOO
AOOA AOOL AOAO AOAA AOAL AOLO AOLA AAOO AAOA AAOL
AALO AALA ALOO ALOA ALAO ALAA LOOO LOOA LOAO LOAA
LAOO LAOA LAAO

How many "prize" strings exist over a 30-day period?

Problem 191: Prize Strings

Mathematical Development

Definition. Let Σ={O,A,L}\Sigma = \{O, A, L\} and let PnΣn\mathcal{P}_n \subseteq \Sigma^n denote the set of prize strings of length nn. Let g(n)g(n) denote the number of strings of length nn over {O,A}\{O, A\} that contain no three consecutive AA‘s.

Theorem 1 (Tribonacci-type recurrence for gg). The function gg satisfies

g(n)=g(n1)+g(n2)+g(n3),n3,g(n) = g(n-1) + g(n-2) + g(n-3), \quad n \ge 3,

with initial values g(0)=1g(0) = 1, g(1)=2g(1) = 2, g(2)=4g(2) = 4.

Proof. We partition the set of valid strings of length nn over {O,A}\{O, A\} (containing no AAAAAA) by the length of the maximal suffix of AA‘s. Every such string falls into exactly one of three disjoint cases:

  • Suffix of zero AA‘s (string ends in OO): the prefix of length n1n - 1 is an arbitrary valid string, giving g(n1)g(n-1) strings.
  • Suffix of exactly one AA (string ends in OAOA, or is AA itself when n=1n=1): for n2n \ge 2, the character at position n2n-2 must be OO, and the prefix of length n2n - 2 is an arbitrary valid string, giving g(n2)g(n-2) strings.
  • Suffix of exactly two AA‘s (string ends in OAAOAA, or is AAAA when n=2n = 2): for n3n \ge 3, the character at position n3n - 3 must be OO (since AAAAAA is forbidden), and the prefix of length n3n - 3 is an arbitrary valid string, giving g(n3)g(n-3) strings.

A suffix of three or more AA‘s is impossible by the constraint. These three cases are exhaustive and mutually exclusive, establishing g(n)=g(n1)+g(n2)+g(n3)g(n) = g(n-1) + g(n-2) + g(n-3) for n3n \ge 3.

The base cases are verified by direct enumeration:

  • g(0)=1g(0) = 1: the empty string ε\varepsilon.
  • g(1)=2g(1) = 2: the strings {O,A}\{O, A\}.
  • g(2)=4g(2) = 4: the strings {OO,OA,AO,AA}\{OO, OA, AO, AA\}. \blacksquare

Theorem 2 (Counting prize strings). The total number of prize strings of length nn is

Pn=g(n)+k=0n1g(k)g(n1k).|\mathcal{P}_n| = g(n) + \sum_{k=0}^{n-1} g(k) \cdot g(n-1-k).

Proof. We partition Pn\mathcal{P}_n by the number of occurrences of LL.

Case 1 (zero LL‘s). The string lies in {O,A}n\{O, A\}^n with no AAAAAA substring. By definition, there are exactly g(n)g(n) such strings.

Case 2 (exactly one LL). Fix the position of LL at index k{0,1,,n1}k \in \{0, 1, \ldots, n-1\} (0-indexed). The string decomposes as

s0s1sk1prefix of length k    L    sk+1sn1suffix of length n1k.\underbrace{s_0 s_1 \cdots s_{k-1}}_{\text{prefix of length } k} \;\; L \;\; \underbrace{s_{k+1} \cdots s_{n-1}}_{\text{suffix of length } n-1-k}.

The prefix is a string over {O,A}\{O, A\} of length kk containing no AAAAAA (counted by g(k)g(k)). The suffix is a string over {O,A}\{O, A\} of length n1kn - 1 - k containing no AAAAAA (counted by g(n1k)g(n-1-k)). Crucially, the LL at position kk interrupts any consecutive-AA run, so the prefix and suffix constraints are independent. By the multiplication principle, there are g(k)g(n1k)g(k) \cdot g(n-1-k) valid strings with LL at position kk. Summing over all kk gives k=0n1g(k)g(n1k)\sum_{k=0}^{n-1} g(k) \cdot g(n-1-k).

Since a prize string has at most one LL, Cases 1 and 2 are exhaustive and disjoint. \blacksquare

Remark. The sum k=0n1g(k)g(n1k)\sum_{k=0}^{n-1} g(k) \cdot g(n-1-k) is a discrete convolution of gg with itself, evaluated at n1n - 1.

Corollary. For n=30n = 30: g(30)=53,798,080g(30) = 53{,}798{,}080 and P30=1,918,080,160|\mathcal{P}_{30}| = 1{,}918{,}080{,}160.

Editorial

Count 30-character strings over {O, A, L} with at most one L and no three consecutive A’s. We compute g[0..n] via the recurrence. Finally, accumulate |P_n|.

Pseudocode

Compute g[0..n] via the recurrence
Accumulate |P_n|

Complexity Analysis

  • Time: O(n)O(n) arithmetic operations — O(n)O(n) for the recurrence and O(n)O(n) for the convolution sum. Each operation involves integers of size O(nlogn)O(n \log n) bits, so the bit-complexity is O(n2logn)O(n^2 \log n), though for n=30n = 30 all values fit in a single machine word.
  • Space: O(n)O(n) to store the array g[0..n]g[0..n]. This can be reduced to O(1)O(1) auxiliary space by accumulating the convolution sum during the forward recurrence pass using a two-pointer technique, though the constant-factor savings are negligible for n=30n = 30.

Answer

1918080160\boxed{1918080160}

Code

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

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

int main() {
    // g[n] = number of valid strings of length n over {O,A} with no "AAA"
    // Recurrence: g[n] = g[n-1] + g[n-2] + g[n-3]
    const int N = 30;
    vector<long long> g(N + 1);
    g[0] = 1; g[1] = 2; g[2] = 4;
    for (int i = 3; i <= N; i++)
        g[i] = g[i-1] + g[i-2] + g[i-3];

    // Strings with 0 L's
    long long ans = g[N];

    // Strings with exactly 1 L: place L at position k, 0-indexed
    // prefix of length k and suffix of length N-1-k must both be valid no-L strings
    for (int k = 0; k < N; k++)
        ans += g[k] * g[N - 1 - k];

    cout << ans << endl;
    return 0;
}