A Stoneham Number
Define the Stoneham number: A = sum_(i=1)^infinity frac13^i * 10^(3^i). Let A(n) denote the 10 decimal digits starting from position n in the decimal expansion of A. Given: A(100) = 4938271604, A(1...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
\[A=\displaystyle \sum _{i=1}^{\infty } \frac {1}{3^i 10^{3^i}}\] Define \(A(n)\) to be the \(10\) decimal digits from the \(n\)th digit onward. For example, \(A(100) = 4938271604\) and \(A(10^8)=2584642393\).
Find \(A(10^{16})\).
Problem 731: A Stoneham Number
Mathematical Foundation
Theorem 1 (Isolated Term Structure). For all , the -th term contributes nonzero digits only at decimal positions . Moreover, for , the digit blocks of and do not overlap in positions .
Proof. The term has its first nonzero decimal digit at position (the factor shifts rightward by places). The decimal expansion of is purely periodic with period , which divides . Hence occupies digits in the range before repeating. Since for all , the repeating block of fits entirely before position where begins. Thus the blocks are isolated.
Lemma 1 (Digit Extraction). The -th decimal digit (after the decimal point) of is
and is computable in arithmetic operations via modular exponentiation.
Proof. Write . By the standard long-division algorithm, and , with . By induction, . Computing uses repeated squaring in multiplications modulo .
Theorem 2 (Digit Block Summation). The 10-digit block equals the last 10 digits of
where is the integer formed by the 10 digits of at positions through , and carries are propagated from right to left.
Proof. Since and the digit blocks are isolated (Theorem 1), only finitely many terms contribute nonzero digits at any given position. Specifically, term can only contribute at position if (otherwise ‘s digits start after position ). The 10-digit block of at position is determined by extracting digits through of via Lemma 1. Summing these integer blocks and propagating carries yields .
Editorial
A = sum_{i=1}^{inf} 1/(3^i * 10^{3^i}) A(n) = 10 digits of A starting at position n. Key: digits at position n come from terms with 3^i <= n+9. For each term, compute digits of 1/3^i at offset n - 3^i using modular exponentiation. We find contributing terms. We then compute 10-digit block for each contributing term. Finally, iterate over i in terms.
Pseudocode
Find contributing terms
Compute 10-digit block for each contributing term
for i in terms
Extract last 10 digits (handle carries)
Complexity Analysis
- Time: . There are contributing terms, each requiring modular exponentiations of cost .
- Space: for storing intermediate values in modular exponentiation.
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 731: A Stoneham Number
*
* A = sum_{i=1}^{inf} 1/(3^i * 10^{3^i})
* A(n) = 10 digits of A starting at decimal position n.
*
* For each term i with 3^i <= n+9, compute digits of 1/3^i at offset (n - 3^i)
* using modular exponentiation: 10^offset mod 3^i.
*/
typedef unsigned long long ull;
typedef __int128 lll;
ull power_mod(ull base, ull exp, ull mod) {
ull result = 1;
base %= mod;
while (exp > 0) {
if (exp & 1) result = (lll)result * base % mod;
base = (lll)base * base % mod;
exp >>= 1;
}
return result;
}
// Get num_digits of 1/3^i starting at position 'start'
vector<int> digits_inv3i(int i, ull start, int num_digits) {
// 3^i as big number - for i up to ~34, this fits in 128 bits
// Use Python for the actual large computation; here demonstrate for small i
ull mod = 1;
for (int j = 0; j < i; j++) mod *= 3;
ull r = power_mod(10, start, mod);
vector<int> result;
for (int k = 0; k < num_digits; k++) {
ull nr = (lll)10 * r;
result.push_back(nr / mod);
r = nr % mod;
}
return result;
}
int main() {
// Verify A(100)
// Terms: i=1 (3^1=3), i=2 (9), i=3 (27), i=4 (81)
int num_digits = 10;
int extra = 20;
ull n = 100;
// For small cases, accumulate
// (Full implementation needs arbitrary precision for large i)
printf("A(10^16) requires Python/mpz for 3^34 modular arithmetic\n");
return 0;
}
"""
Problem 731: A Stoneham Number
A = sum_{i=1}^{inf} 1/(3^i * 10^{3^i})
A(n) = 10 digits of A starting at position n.
Key: digits at position n come from terms with 3^i <= n+9.
For each term, compute digits of 1/3^i at offset n - 3^i using modular exponentiation.
"""
def digits_of_inv3i(i, start, count):
"""Get 'count' decimal digits of 1/3^i starting at position 'start' (0-indexed after decimal point).
The j-th digit (0-indexed) of 1/3^i is floor(10^{j+1} / 3^i) mod 10.
Equivalently, compute 10^{start+k} mod (10 * 3^i) for k = 0..count-1.
"""
mod = 3 ** i
result = 0
for k in range(count):
pos = start + k
# digit at position pos (1-indexed) = floor(10^pos mod (10*mod)) / mod
# = (10^pos mod (10*mod)) // mod ... no, simpler:
# digit = (10^pos * 10 // mod) ... nah.
# 1/3^i = 0.d1 d2 d3 ...
# d_j (1-indexed) = floor(10^j / 3^i) - 10 * floor(10^{j-1} / 3^i)
# = floor(10 * (10^{j-1} mod 3^i) / 3^i)
# So: remainder r = 10^{j-1} mod 3^i, then digit = (10*r) // 3^i
# and new remainder = (10*r) mod 3^i
pass
# Better approach: compute starting remainder, then iterate
mod = 3 ** i
r = pow(10, start, mod) # 10^start mod 3^i
digits = []
for k in range(count):
d = (10 * r) // mod
r = (10 * r) % mod
digits.append(d)
return digits
def stoneham_A(n, num_digits=10):
"""Compute A(n) = 10 decimal digits of the Stoneham number starting at position n."""
# Find all i with 3^i <= n + num_digits - 1
max_i = 0
power3 = 3
while power3 <= n + num_digits - 1:
max_i += 1
power3 *= 3
# Accumulate digit contributions
# We work with a large integer: sum of contributions * 10^extra for carries
extra = 20 # extra digits for carry safety
total = 0
power3 = 3
for i in range(1, max_i + 1):
offset = n - power3 # position in 1/3^i expansion
if offset < 0:
power3 *= 3
continue
digs = digits_of_inv3i(i, offset, num_digits + extra)
# Convert to integer
val = 0
for d in digs:
val = val * 10 + d
total += val
power3 *= 3
# Extract top num_digits digits
s = str(total)
# The result is the first num_digits digits of the sum
# But we need to handle carries: the sum might produce more digits
result = s[:num_digits]
return int(result)
# Verify
a100 = stoneham_A(100)
print(f"A(100) = {a100}") # Expected: 4938271604
assert a100 == 4938271604, f"Got {a100}"
# A(10^8) - this works but takes a moment
a_1e8 = stoneham_A(10**8)
print(f"A(10^8) = {a_1e8}") # Expected: 2584642393
# A(10^16)
a_1e16 = stoneham_A(10**16)
print(f"A(10^16) = {a_1e16}")