All Euler problems
Project Euler

Golomb's Self-Describing Sequence

The Golomb sequence {G(n)}_(n >= 1) is the unique non-decreasing sequence of positive integers satisfying the self-referential property: for every positive integer n, the value n appears exactly G(...

Source sync Apr 19, 2026
Problem #0341
Level Level 15
Solved By 1,090
Languages C++, Python
Answer 56098610614277014
Length 555 words
sequenceanalytic_mathlinear_algebra

Problem Statement

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

The Golomb’s self-describing sequence \((G(n))\) is the only nondecreasing sequence of natural numbers such that \(n\) appears exactly \(G(n)\) times in the sequence. The values of \(G(n)\) for the first few \(n\) are

\(n\) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
\(G(n)\) 1 2 2 3 3 4 4 4 5 5 5 6 6 6 6

You are given that \(G(10^3) = 86\), \(G(10^6) = 6137\).

You are also given that \(\displaystyle \sum G(n^3) = 153506976\) for \(1 \le n < 10^3\).

Find \(\displaystyle \sum G(n^3)\) for \(1 \le n < 10^6\).

Problem 341: Golomb’s Self-Describing Sequence

Mathematical Foundation

Definition 1 (Block decomposition). Since GG is non-decreasing and the value vv appears exactly G(v)G(v) times, the sequence partitions into consecutive blocks: the vv-th block consists of G(v)G(v) copies of vv, occupying positions P(v1)+1P(v-1)+1 through P(v)P(v), where

P(v)i=1vG(i)P(v) \coloneqq \sum_{i=1}^{v} G(i)

is the cumulative position function, with P(0)0P(0) \coloneqq 0.

Theorem 1 (Golomb recurrence). The sequence satisfies G(1)=1G(1) = 1 and

G(n)=1+G(nG(G(n1)))for n2.G(n) = 1 + G\bigl(n - G(G(n-1))\bigr) \quad \text{for } n \ge 2.

Proof. Let n2n \ge 2 and suppose G(n1)=vG(n-1) = v, so position n1n-1 lies in the block for value vv. By the self-describing property, value vv occupies G(v)G(v) positions, of which G(G(v))=G(G(n1))G(G(v)) = G(G(n-1)) positions precede or equal position n1n-1 within the block structure induced by GG. The index nG(G(n1))n - G(G(n-1)) therefore falls in the block for value v1v-1 or earlier, and since the sequence is non-decreasing with unit increments between consecutive block values, we obtain G(n)=1+G(nG(G(n1)))G(n) = 1 + G(n - G(G(n-1))). \square

Lemma 1 (Block-based evaluation of GG). For any position nn satisfying P(v1)<nP(v)P(v-1) < n \le P(v), we have G(n)=vG(n) = v. Equivalently, G(n)=vG(n) = v if and only if nn lies in the vv-th block.

Proof. By Definition 1, positions P(v1)+1P(v-1)+1 through P(v)P(v) constitute the vv-th block, and every entry in this block equals vv. The blocks are disjoint, contiguous, and cover all positive integers, so the characterization is both necessary and sufficient. \square

Lemma 2 (Cumulative weighted sum). Define the cumulative weighted sum S(v)i=1viG(i)S(v) \coloneqq \sum_{i=1}^{v} i \cdot G(i), with S(0)0S(0) \coloneqq 0. Then S(v)S(v) records the sum k=1P(v)G(k)\sum_{k=1}^{P(v)} G(k), i.e., the sum of all sequence values through the end of the vv-th block.

Proof. By partitioning the sum over blocks:

k=1P(v)G(k)=i=1viG(i)block i contributes G(i) copies of i=S(v).\sum_{k=1}^{P(v)} G(k) = \sum_{i=1}^{v} \underbrace{i \cdot G(i)}_{\text{block } i \text{ contributes } G(i) \text{ copies of } i} = S(v). \quad \square

Proposition 1 (Partial-block interpolation). For a position nn with P(v1)<nP(v)P(v-1) < n \le P(v):

k=1nG(k)=S(v1)+v(nP(v1)).\sum_{k=1}^{n} G(k) = S(v-1) + v \cdot \bigl(n - P(v-1)\bigr).

Proof. The first P(v1)P(v-1) terms contribute S(v1)S(v-1). The remaining nP(v1)n - P(v-1) terms all lie in the vv-th block, each equal to vv. \square

Theorem 2 (Asymptotic growth — Golomb 1966). As nn \to \infty,

G(n)ϕ2ϕnϕ1,G(n) \sim \phi^{2-\phi}\, n^{\phi - 1},

where ϕ=1+52\phi = \frac{1+\sqrt{5}}{2} is the golden ratio. Consequently, P(v)CvϕP(v) \sim C \cdot v^{\phi} for an explicit constant CC, and the block index vv corresponding to position nn satisfies v=O(n1/ϕ)v = O(n^{1/\phi}).

Proof. The self-describing property imposes G(G(n))n(ϕ1)2=n2ϕG(G(n)) \sim n^{(\phi-1)^2} = n^{2-\phi} on the one hand, and G(G(n))G(n)(ϕ1)G(G(n)) \sim G(n)^{(\phi-1)} on the other. Equating exponents yields (ϕ1)2=2ϕ(\phi-1)^2 = 2-\phi, which is precisely the defining equation ϕ2=ϕ+1\phi^2 = \phi + 1 of the golden ratio. The prefactor ϕ2ϕ\phi^{2-\phi} is determined by carrying the asymptotic through the recurrence; see Golomb (1966). \square

Corollary 1 (Sufficient computation range). To evaluate G(n)G(n) for nn up to (106)3=1018(10^6)^3 = 10^{18}, it suffices to compute the Golomb sequence through block index vmax=O((1018)1/ϕ)O(1011.1)v_{\max} = O\bigl((10^{18})^{1/\phi}\bigr) \approx O(10^{11.1}). In practice, building P(v)P(v) incrementally until P(v)1018P(v) \ge 10^{18} determines vmaxv_{\max}.

Editorial

The Golomb sequence G satisfies: value v appears exactly G(v) times. Recurrence: G(1) = 1, G(n) = 1 + G(n - G(G(n-1))) for n >= 2. Define P(v) = sum_{i=1}^{v} G(i) (last position with value <= v). Then G(n) = v iff P(v-1) < n <= P(v). We build the sequence until P(v) >= (10^6 - 1)^3, then for each d = 1..999999 locate the block containing d^3 via a linear scan. We build blocks.** Compute G(v)G(v), P(v)P(v), and S(v)S(v) for v=1,2,v = 1, 2, \ldots using the recurrence until P(v)(1061)3P(v) \ge (10^6 - 1)^3. Finally, answer queries.** For each d=1,,999999d = 1, \ldots, 999999, set n=d3n = d^3. Locate the block vv such that P(v1)<nP(v)P(v-1) < n \le P(v) using a linear scan (since queries are in increasing order of d3d^3, the scan pointer only advances). Then G(n)=vG(n) = v, and accumulate vv into the total.

Pseudocode

    Build G, P, S arrays until P[v] >= (10^6 - 1)^3
    index = 1, total = 0
    For d from 1 to 999999:
        n = d^3
        While P[index] < n:
            index += 1
        total += index // G(n) = index since P[index-1] < n <= P[index]
    Return total

Complexity Analysis

  • Time: O(V+N)O(V + N) where VV is the number of Golomb values computed (empirically 107\approx 10^7) and N=999999N = 999999 queries are answered by a single linear scan.
  • Space: O(V)O(V) for storing the arrays GG, PP.

Answer

56098610614277014\boxed{56098610614277014}

Code

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

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

/*
 * Problem 341: Golomb's Self-Describing Sequence
 *
 * G(1) = 1, G(n) = 1 + G(n - G(G(n-1))) for n >= 2.
 * Value v appears G(v) times.  P(v) = sum_{i=1}^{v} G(i) is the last
 * position with value <= v.  G(n) = v iff P(v-1) < n <= P(v).
 *
 * Build blocks until P(v) >= (10^6-1)^3, then answer each query G(d^3)
 * by a linear scan through the blocks.
 *
 * Answer: 56098610614277014
 */

int main(){
    const long long LIMIT = 1000000;
    const long long cubicLimit = (LIMIT - 1) * (LIMIT - 1) * (LIMIT - 1);

    // Build Golomb sequence: G[v] and P[v]
    vector<long long> G = {0, 1};
    vector<long long> P = {0, 1};
    G.reserve(12000000);
    P.reserve(12000000);

    for (long long v = 2; P.back() < cubicLimit; v++) {
        long long g = 1 + G[v - G[G[v - 1]]];
        G.push_back(g);
        P.push_back(P.back() + g);
    }

    // Answer queries G(d^3) for d = 1..999999 via linear scan
    long long total = 0;
    long long idx = 1;
    for (long long d = 1; d < LIMIT; d++) {
        long long n = d * d * d;
        while (P[(size_t)idx] < n)
            idx++;
        total += idx;
    }

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