Digital Root Sums of Factorisations
The digital root of a number is found by repeatedly summing its digits until a single digit remains. For example, dr(627) = dr(15) = 6. For a composite number n, a "digital root sum" (drs) of a fac...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
A composite number can be factored many different ways.
For instance, not including multiplication by one, $24$ can be factored in $7$ distinct ways: \begin{align*} 24 &= 2 \times 2 \times 2 \times 3\\ 24 &= 2 \times 3 \times 4\\ 24 &= 2 \times 2 \times 6\\ 24 &= 4 \times 6\\ 24 &= 3 \times 8\\ 24 &= 2 \times 12\\ 24 &= 24 \end{align*} Recall that the digital root of a number, in base $10$, is found by adding together the digits of that number, and repeating that process until a number is arrived at that is less than $10$. Thus the digital root of $467$ is $8$.
We shall call a Digital Root Sum (DRS) the sum of the digital roots of the individual factors of our number.
The chart below demonstrates all of the DRS values for $24$.
| Factorisation | Digital Root Sum |
| $2 \times 2 \times 2 \times 2$ | $9$ |
| $2 \times 3 \times 4$ | $9$ |
| $2 \times 2 \times 6$ | $10$ |
| $4 \times 6$ | $10$ |
| $3 \times 8$ | $11$ |
| $2 \times 12$ | $5$ |
| $24$ | $6$ |
The maximum Digital Root Sum of $24$ is $11$.
The function $\operatorname{mdrs}(n)$ gives the maximum Digital Root Sum of $n$. So $\operatorname{mdrs}(24)=11$.
Find $\displaystyle \sum \operatorname{mdrs}(n)$ for $1 < n < 1\,000\,000$.
Problem 159: Digital Root Sums of Factorisations
Mathematical Analysis
Digital root formula
The digital root has a well-known closed form:
for . Equivalently, if , and if (for ).
Key property
For the digital root sum, note that in general. This means splitting a factor into smaller factors can only maintain or increase the digital root sum.
Dynamic programming approach
We compute using a sieve-like approach:
Initialize for all (the trivial factorization with itself).
Then for each from 2 to , for each multiple where :
This works because the optimal factorization of either has as a single factor (giving ), or splits as for some , and we use the optimal factorization of .
We iterate from 2 upward, and for each , update all multiples. Since we process in increasing order and use the already-computed values, this correctly computes the maximum.
Correctness
If the optimal factorization of is , then:
- The smallest factor is .
- The remaining product is with .
- .
Since we iterate from 2 up and update to the maximum of its current value and , we capture this optimal split.
Correctness
Theorem. The method described above computes exactly the quantity requested in the problem statement.
Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer.
Complexity
The sieve runs in time where , since for each , we process multiples.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
const int LIMIT = 1000000;
int dr(int n) {
if (n == 0) return 0;
int r = n % 9;
return r == 0 ? 9 : r;
}
int mdrs[LIMIT];
int main() {
ios::sync_with_stdio(false);
// Initialize mdrs[n] = dr(n)
for (int n = 2; n < LIMIT; n++) {
mdrs[n] = dr(n);
}
// Sieve: for each factor a >= 2, update multiples
for (int a = 2; a * a < LIMIT; a++) {
for (int j = a; (long long)a * j < LIMIT; j++) {
int n = a * j;
mdrs[n] = max(mdrs[n], dr(a) + mdrs[j]);
}
}
long long total = 0;
for (int n = 2; n < LIMIT; n++) {
total += mdrs[n];
}
cout << total << endl;
return 0;
}
LIMIT = 1000000
def dr(n):
"""Digital root of n."""
if n == 0:
return 0
r = n % 9
return 9 if r == 0 else r
# Initialize mdrs[n] = dr(n)
mdrs = [0] * LIMIT
for n in range(2, LIMIT):
mdrs[n] = dr(n)
# Sieve: for each factor a >= 2, update all multiples a*j where j >= a
a = 2
while a * a < LIMIT:
j = a
while a * j < LIMIT:
n = a * j
val = dr(a) + mdrs[j]
if val > mdrs[n]:
mdrs[n] = val
j += 1
a += 1
total = sum(mdrs[2:])
print(total)