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(...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
The
| \(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 is non-decreasing and the value appears exactly times, the sequence partitions into consecutive blocks: the -th block consists of copies of , occupying positions through , where
is the cumulative position function, with .
Theorem 1 (Golomb recurrence). The sequence satisfies and
Proof. Let and suppose , so position lies in the block for value . By the self-describing property, value occupies positions, of which positions precede or equal position within the block structure induced by . The index therefore falls in the block for value or earlier, and since the sequence is non-decreasing with unit increments between consecutive block values, we obtain .
Lemma 1 (Block-based evaluation of ). For any position satisfying , we have . Equivalently, if and only if lies in the -th block.
Proof. By Definition 1, positions through constitute the -th block, and every entry in this block equals . The blocks are disjoint, contiguous, and cover all positive integers, so the characterization is both necessary and sufficient.
Lemma 2 (Cumulative weighted sum). Define the cumulative weighted sum , with . Then records the sum , i.e., the sum of all sequence values through the end of the -th block.
Proof. By partitioning the sum over blocks:
Proposition 1 (Partial-block interpolation). For a position with :
Proof. The first terms contribute . The remaining terms all lie in the -th block, each equal to .
Theorem 2 (Asymptotic growth — Golomb 1966). As ,
where is the golden ratio. Consequently, for an explicit constant , and the block index corresponding to position satisfies .
Proof. The self-describing property imposes on the one hand, and on the other. Equating exponents yields , which is precisely the defining equation of the golden ratio. The prefactor is determined by carrying the asymptotic through the recurrence; see Golomb (1966).
Corollary 1 (Sufficient computation range). To evaluate for up to , it suffices to compute the Golomb sequence through block index . In practice, building incrementally until determines .
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 , , and for using the recurrence until . Finally, answer queries.** For each , set . Locate the block such that using a linear scan (since queries are in increasing order of , the scan pointer only advances). Then , and accumulate 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: where is the number of Golomb values computed (empirically ) and queries are answered by a single linear scan.
- Space: for storing the arrays , .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#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;
}
"""
Problem 341: Golomb's Self-Describing Sequence
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.
Answer: 56098610614277014
"""
def solve():
limit = 1000000
cubic_limit = (limit - 1) ** 3
# Build Golomb sequence: G[v], P[v] = cumulative position
G = [0, 1]
P = [0, 1]
v = 1
while P[v] < cubic_limit:
v += 1
g = 1 + G[v - G[G[v - 1]]]
G.append(g)
P.append(P[v - 1] + g)
# Answer queries G(d^3) for d = 1..999999 using linear scan
total = 0
idx = 1
for d in range(1, limit):
n = d * d * d
while P[idx] < n:
idx += 1
total += idx
print(total)
if __name__ == "__main__":
solve()