Project Euler/92: Difference between revisions
From charlesreid1
(Create Project Euler/92 page with problem statement, solution approach, and Java solution (via create-page on MediaWiki MCP Server)) |
(replace source tag with syntaxhighlight tag (via update-page on MediaWiki MCP Server)) |
||
| Line 1: | Line 1: | ||
This is problem 92 on Project Euler: https://projecteuler.net/problem=92 | This is problem 92 on Project Euler: https://projecteuler.net/problem=92 | ||
| Line 42: | Line 43: | ||
: https://git.charlesreid1.com/cs/euler/src/branch/main/java/Problem092.java | : https://git.charlesreid1.com/cs/euler/src/branch/main/java/Problem092.java | ||
< | <syntaxhighlight lang="java"> | ||
public class Problem092 { | public class Problem092 { | ||
| Line 76: | Line 77: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
=Flags= | =Flags= | ||
Latest revision as of 17:20, 24 June 2026
This is problem 92 on Project Euler: https://projecteuler.net/problem=92
Overview of the Problem
Question
A number chain is created by continuously adding the square of the digits in a number to form a new number until it has been seen before. For example,
- $ 44 \to 32 \to 13 \to 10 \to \mathbf{1} \to \mathbf{1} $
- $ 85 \to \mathbf{89} \to 145 \to 42 \to 20 \to 4 \to 16 \to 37 \to 58 \to \mathbf{89} $
Therefore any chain that arrives at $ 1 $ or $ 89 $ will become stuck in an endless loop. What is most amazing is that every starting number will eventually arrive at $ 1 $ or $ 89 $.
How many starting numbers below ten million will arrive at $ 89 $?
Solution Approach
The key observation for this problem is that the sum of squared digits for any number below ten million is at most $ 7 \times 9^2 = 567 $. This means every chain quickly collapses into the small state space $ 1 \dots 567 $.
We can break the problem into two phases:
Phase 1: Precompute chain destinations for 1 through 567
For each integer $ s $ from $ 1 $ to $ 567 $, follow its digit-square-sum chain until it reaches either $ 1 $ or $ 89 $. Cache the result (a boolean: true if the chain arrives at $ 89 $) in an array. Walking the chain is cheap because these numbers are small, and once a chain hits a previously cached value, we can short-circuit.
Phase 2: Count arrivals at 89 for all numbers below ten million
For each starting number $ n $ from $ 1 $ to $ 9,999,999 $:
- Compute $ s = \text{sumOfSquaredDigits}(n) $. This value is in the range $ 0 \dots 567 $.
- Look up the cached result for $ s $.
- If the cached result is
true(i.e., the chain ultimately reaches $ 89 $), increment the count.
The sumOfSquaredDigits helper repeatedly extracts the last digit of $ n $, squares it, adds it to a running sum, and divides $ n $ by $ 10 $.
This approach runs in $ O(N \cdot d) $ time where $ N = 10^7 $ and $ d \approx 7 $ digits, making it fast enough for a single-threaded Java implementation.
Java Solution
The full implementation is available in the Euler Git repository:
public class Problem092 {
private static int sumOfSquaredDigits(int n) {
int sum = 0;
while (n > 0) {
int d = n % 10;
sum += d * d;
n /= 10;
}
return sum;
}
public static void main(String[] args) {
boolean[] cache = new boolean[568];
for (int i = 1; i <= 567; i++) {
int n = i;
while (n != 1 && n != 89) {
n = sumOfSquaredDigits(n);
}
cache[i] = (n == 89);
}
int count = 0;
for (int i = 1; i < 10_000_000; i++) {
if (cache[sumOfSquaredDigits(i)]) {
count++;
}
}
System.out.println(count);
}
}
Flags