Champernowne's Constant
An irrational decimal fraction is created by concatenating the positive integers: 0.123456789101112131415161718192021... If d_n represents the n -th digit of the fractional part, find the value of:...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
An irrational decimal fraction is created by concatenating the positive integers: $$0.12345678910{\color{red}\mathbf 1}112131415161718192021\cdots$$ It can be seen that the $12^{th}$ digit of the fractional part is $1$.
If $d_n$ represents the $n^{th}$ digit of the fractional part, find the value of the following expression. $$d_1 \times d_{10} \times d_{100} \times d_{1000} \times d_{10000} \times d_{100000} \times d_{1000000}$$
Problem 40: Champernowne’s Constant
Mathematical Development
Mathematical Foundation
Definition. Champernowne’s constant (base 10) is , formed by concatenating all positive integers in order. We denote by the -th digit of the fractional part.
Theorem 1 (Block structure). The digits of Champernowne’s constant are partitioned into blocks by digit count . The -digit positive integers range from to , contributing a total of digits.
Proof. The number of -digit positive integers is . Each contributes digits to the concatenation, giving digits total from the -digit block.
Lemma 1 (Cumulative digit positions). Let be the cumulative number of digits contributed by all integers with at most digits. Then:
| 1 | 9 | 9 |
| 2 | 180 | 189 |
| 3 | 2700 | 2889 |
| 4 | 36000 | 38889 |
| 5 | 450000 | 488889 |
| 6 | 5400000 | 5888889 |
Proof. Direct computation: , , , etc.
Theorem 2 (Digit extraction algorithm). To find :
- Find the unique such that (with ).
- Compute the offset within the -digit block.
- The integer containing the -th digit is .
- The position within is (0-indexed from the left).
- Then is the -th digit (from the left) of .
Proof. After consuming digits from all integers with fewer than digits, position falls within the -digit block. The offset counts how many digits into this block position lies. Since each -digit integer contributes exactly digits, the -th integer in the block (0-indexed) is . Within this integer, the digit position is from the left.
Theorem 3 (Computation of required digits). Applying Theorem 2 to each required position:
-
: , . Integer . Digit index of “1” .
-
: , . Integer . Digit index of “10” .
-
: , . Integer . Digit index of “55” .
-
: , . Integer . Digit index of “370” .
-
: , . Integer . Digit index of “2777” .
-
: , . Integer . Digit index of “22222” .
-
: , . Integer . Digit index of “185185” .
Proof. Each computation follows directly from Theorem 2 with the values from Lemma 1.
Editorial
We use the block decomposition of Champernowne’s constant by digit length. For any requested position , the procedure first determines which block of -digit integers contains that position by removing the contributions of all shorter blocks. The remaining offset identifies the exact integer in the -digit block and the exact digit inside that integer. Repeating this extraction for the seven positions and multiplying the resulting digits yields the required product.
Pseudocode
Algorithm: Digit of Champernowne Constant
Require: An integer n ≥ 1.
Ensure: The digit d_n in the fractional part of Champernowne's constant.
1: Initialize k ← 1, block ← 9, and offset ← n.
2: While offset > k · block do:
3: Update offset ← offset - k · block, k ← k + 1, and block ← 9 · 10^(k - 1).
4: Set q ← 10^(k - 1) + floor((offset - 1) / k) and j ← (offset - 1) mod k.
5: Return the (j + 1)-st digit of q from the left.
Algorithm: Champernowne Digit Product
Require: The target positions {10^0, 10^1, ..., 10^6}.
Ensure: The product ∏_{i=0}^6 d_(10^i).
1: Initialize P ← 1.
2: For each i in {0, 1, ..., 6} do:
3: Compute d ← DigitOfChampernowneConstant(10^i) and update P ← P · d.
4: Return P.
Complexity Analysis
- Time: per digit query, since we iterate through at most blocks. With 7 queries and , total time is .
- Space: . Only a constant number of variables are needed.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int champernowne_digit(int n) {
int k = 1;
long long count = 9;
long long start = 1;
while (n > k * count) {
n -= k * count;
k++;
count *= 10;
start *= 10;
}
// n is now the position within the k-digit block (1-indexed)
long long number = start + (n - 1) / k;
int digit_pos = (n - 1) % k;
string s = to_string(number);
return s[digit_pos] - '0';
}
int main() {
long long product = 1;
for (int exp = 0; exp <= 6; exp++) {
int pos = 1;
for (int i = 0; i < exp; i++) pos *= 10;
int d = champernowne_digit(pos);
product *= d;
}
cout << product << endl;
return 0;
}
"""
Project Euler Problem 40: Champernowne's Constant
Find d_1 * d_10 * d_100 * d_1000 * d_10000 * d_100000 * d_1000000
where d_n is the n-th digit of Champernowne's constant 0.123456789101112...
"""
def champernowne_digit(n: int):
"""Find the n-th digit (1-indexed) of the Champernowne sequence."""
k = 1
count = 9
start = 1
while n > k * count:
n -= k * count
k += 1
count *= 10
start *= 10
# n is now position within the k-digit block (1-indexed)
number = start + (n - 1) // k
digit_pos = (n - 1) % k
return int(str(number)[digit_pos])
def solve():
positions = [10**i for i in range(7)] # 1, 10, 100, ..., 1000000
digits = []
product = 1
for pos in positions:
d = champernowne_digit(pos)
digits.append((pos, d))
product *= d
return product, digits
product, digits = solve()
print("Champernowne's constant digit lookup:")
for pos, d in digits:
print(f" d_{pos:>7d} = {d}")
print(f"\nProduct = {' x '.join(str(d) for _, d in digits)} = {product}")
# Verification using brute force
champernowne = ""
i = 1
while len(champernowne) < 1_000_001:
champernowne += str(i)
i += 1
product_verify = 1
for pos in [1, 10, 100, 1000, 10000, 100000, 1000000]:
product_verify *= int(champernowne[pos - 1])
print(f"Verification (brute force): {product_verify}")