Repunit Divisibility
A repunit R_n is a number consisting of n ones: R_n = underbrace11ldots1_n = (10^n - 1)/(9). Find the sum of all n <= 1000 such that R_n is divisible by n.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
This game starts with a positive integer. Two players take turns to remove a single digit from that integer. After the digit is removed any resulting leading zeros are removed.
For example, removing a digit from \(105\) results in either \(5\), \(10\) or \(15\).
The winner is the person who removes the last nonzero digit.
Define \(W(N)\) to be how many positive integers less than \(N\) for which the first player can guarantee a win given optimal play. You are given \(W(100) = 18\) and \(W(10^4) = 1656\).
Find \(W(10^{18})\).
Problem 961: Repunit Divisibility
Mathematical Foundation
Theorem 1 (Divisibility Criterion). Let . Then if and only if .
Proof. We have . Since implies , we compute:
The second equivalence holds because is always true (since , so ), hence if and only if .
Lemma 1 (Even and 5-divisible exclusion). If and or , then .
Proof. Every repunit consists entirely of the digit 1, so is odd for all (since and the last digit is 1). Similarly, for all . Therefore and , which means if or (with ), then .
Theorem 2 (Powers of 3). For all , .
Proof. By induction on .
Base case (): , so .
Inductive step: Assume . Using the factorization identity for repunits:
set , so .
Since , we have .
By the inductive hypothesis , and the cofactor is divisible by 3, so .
Lemma 2 (Multiplicative order characterization). For , let be the multiplicative order of 10 modulo . Then if and only if .
Proof. By Theorem 1, . By definition of multiplicative order, if and only if .
Editorial
R_n = (10^n - 1) / 9 = 111…1 (n ones). Find sum of all n <= 1000 such that n | R_n. Equivalently: 9n | (10^n - 1), i.e., 10^n = 1 (mod 9n). Only possible when gcd(n, 10) = 1 (n odd, not divisible by 5). Complexity: O(N log N) with modular exponentiation.
Pseudocode
total = 0
For n from 1 to N:
If gcd(n, 10) != 1 then
continue
If ModPow(10, n, 9*n) == 1 then
total = total + n
Return total
result = 1
base = base mod mod
While exp > 0:
if exp is odd:
result = (result * base) mod mod
exp = exp >> 1
base = (base * base) mod mod
Return result
Complexity Analysis
- Time: . For each of the candidate values of , binary modular exponentiation computes in multiplications.
- Space: . Only a constant number of variables are maintained.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
/*
* Problem 961: Repunit Divisibility
*
* Find sum of n <= 1000 such that n | R_n where R_n = (10^n - 1)/9.
* Equivalently: 10^n = 1 (mod 9n), for gcd(n, 10) = 1.
*
* Complexity: O(N log N) with binary exponentiation.
*/
#include <bits/stdc++.h>
using namespace std;
long long power(long long base, long long exp, long long mod) {
long long result = 1;
base %= mod;
while (exp > 0) {
if (exp & 1) result = result * base % mod;
base = base * base % mod;
exp >>= 1;
}
return result;
}
int main() {
const int N = 1000;
long long total = 0;
for (int n = 1; n <= N; n++) {
if (n % 2 == 0 || n % 5 == 0) continue; // gcd(n,10) > 1
long long mod = 9LL * n;
if (power(10, n, mod) == 1) {
total += n;
}
}
// n=1 is special: R_1 = 1, 1|1
// Already handled since gcd(1,10)=1 and 10^1 mod 9 = 1
cout << total << endl;
return 0;
}
"""
Problem 961: Repunit Divisibility
R_n = (10^n - 1) / 9 = 111...1 (n ones).
Find sum of all n <= 1000 such that n | R_n.
Equivalently: 9n | (10^n - 1), i.e., 10^n = 1 (mod 9n).
Only possible when gcd(n, 10) = 1 (n odd, not divisible by 5).
Complexity: O(N log N) with modular exponentiation.
"""
from math import gcd
def is_repunit_divisible(n: int) -> bool:
"""Check if n divides R_n = (10^n - 1) / 9."""
if n == 1:
return True
if gcd(n, 10) > 1:
return False
return pow(10, n, 9 * n) == 1
def solve(N: int = 1000) -> tuple[int, list[int]]:
"""Find sum of all n <= N with n | R_n."""
qualifying = [n for n in range(1, N + 1) if is_repunit_divisible(n)]
return sum(qualifying), qualifying
# --- Compute answer ---
answer, qualifying = solve(1000)
# Verify small cases
assert is_repunit_divisible(1) # R_1 = 1, 1|1
assert is_repunit_divisible(3) # R_3 = 111 = 37*3
assert is_repunit_divisible(9) # R_9 = 111111111 / 9 = 12345679... 9 | 111111111
assert not is_repunit_divisible(2)
assert not is_repunit_divisible(5)
print(f"Qualifying values: {qualifying}")
print(answer)