Repunit Nonfactors
A repunit R(k) = (10^k - 1)/(9). Find the sum of all primes below 100,000 that will never be a factor of R(10^n) for any positive integer n.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
A number consisting entirely of ones is called a repunit. We shall define \(R(k)\) to be a repunit of length \(k\); for example, \(R(6) = 111111\).
Let us consider repunits of the form \(R(10^n)\).
Although \(R(10)\), \(R(100)\), or \(R(1000)\) are not divisible by \(17\), \(R(10000)\) is divisible by \(17\). Yet there is no value of \(n\) for which \(R(10^n)\) will divide by \(19\). In fact, it is remarkable that \(11\), \(17\), \(41\), and \(73\) are the only four primes below one-hundred that can be a factor of \(R(10^n)\).
Find the sum of all the primes below one-hundred thousand that will never be a factor of \(R(10^n)\).
Problem 133: Repunit Nonfactors
Mathematical Development
Theorem 1 (5-Smooth Order Criterion). For a prime with and , there exists a positive integer such that if and only if is 5-smooth (i.e., all prime factors of lie in ).
Proof. By the divisibility theory for repunits (Theorem 1 of Problem 132), iff . Therefore:
() If for some , then every prime factor of divides , so is 5-smooth.
() If , take . Then is divisible by , so .
Lemma 1 (Permanent Nonfactors). The primes , , and never divide for any .
Proof. The repunit is odd (so ) and ends in digit 1 (so ), for all .
For : since (verifiable: ), we have . Since implies for all , the prime 3 never divides .
Lemma 2 (Efficient Testing). For , the condition ” is 5-smooth” is equivalent to , where .
Proof. Since , any 5-smooth divisor of is of the form with and . Hence , and the claim follows from the definition of multiplicative order.
Conversely, if , then , so is 5-smooth.
Remark. An equivalent approach computes explicitly by factoring and refining, then checks 5-smoothness by dividing out all factors of 2 and 5.
Editorial
A prime p (not 2, 3, 5) can divide some R(10^n) iff ord_p(10) is 5-smooth. We iterate over p in primes.
Pseudocode
N = 100000
primes = sieve_primes(N)
total = 0
for p in primes:
If p in {2, 3, 5} then
total += p // permanent nonfactors
continue
d = multiplicative_order(10, p)
If not is_5_smooth(d) then
total += p // nonfactor
Return total
Complexity Analysis
- Time: for the sieve. For each prime , computing requires factoring in time and modular exponentiations. Over all primes, the total is in the worst case, though typically much faster.
- Space: for the sieve.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
/*
* Project Euler Problem 133: Repunit Nonfactors
*
* Sum of all primes below 100000 that never divide R(10^n).
* A prime p can divide some R(10^n) iff ord_p(10) is 5-smooth.
*/
#include <bits/stdc++.h>
using namespace std;
long long power_mod(long long base, long long exp, long long mod) {
long long result = 1;
base %= mod;
while (exp > 0) {
if (exp & 1) result = (__int128)result * base % mod;
base = (__int128)base * base % mod;
exp >>= 1;
}
return result;
}
int main() {
const int LIMIT = 100000;
vector<bool> is_prime(LIMIT, true);
is_prime[0] = is_prime[1] = false;
for (int i = 2; i * i < LIMIT; i++)
if (is_prime[i])
for (int j = i * i; j < LIMIT; j += i)
is_prime[j] = false;
long long total = 0;
for (int p = 2; p < LIMIT; p++) {
if (!is_prime[p]) continue;
if (p == 2 || p == 3 || p == 5) {
total += p;
continue;
}
// Compute ord_p(10) by factoring p-1 and refining
int pm1 = p - 1;
vector<int> factors;
int temp = pm1;
for (int f = 2; (long long)f * f <= temp; f++) {
if (temp % f == 0) {
factors.push_back(f);
while (temp % f == 0) temp /= f;
}
}
if (temp > 1) factors.push_back(temp);
int d = pm1;
for (int f : factors)
while (d % f == 0 && power_mod(10, d / f, p) == 1)
d /= f;
// Check if d is 5-smooth
int dd = d;
while (dd % 2 == 0) dd /= 2;
while (dd % 5 == 0) dd /= 5;
if (dd != 1)
total += p;
}
cout << total << endl;
return 0;
}
"""
Project Euler Problem 133: Repunit Nonfactors
Find the sum of all primes below 100000 that never divide R(10^n).
A prime p (not 2, 3, 5) can divide some R(10^n) iff ord_p(10) is 5-smooth.
"""
def sieve(limit):
is_prime = [True] * limit
is_prime[0] = is_prime[1] = False
for i in range(2, int(limit**0.5) + 1):
if is_prime[i]:
for j in range(i * i, limit, i):
is_prime[j] = False
return [i for i in range(2, limit) if is_prime[i]]
def multiplicative_order(a, n):
"""Compute ord_n(a) by factoring n-1 and refining."""
if n <= 1:
return 1
pm1 = n - 1
factors = []
temp = pm1
f = 2
while f * f <= temp:
if temp % f == 0:
factors.append(f)
while temp % f == 0:
temp //= f
f += 1
if temp > 1:
factors.append(temp)
d = pm1
for f in factors:
while d % f == 0 and pow(a, d // f, n) == 1:
d //= f
return d
def is_5_smooth(n):
while n % 2 == 0:
n //= 2
while n % 5 == 0:
n //= 5
return n == 1
LIMIT = 100000
primes = sieve(LIMIT)
total = 0
for p in primes:
if p in (2, 3, 5):
total += p
continue
d = multiplicative_order(10, p)
if not is_5_smooth(d):
total += p
print(total)