Print Strong Numbers in a Range in Java
Problem
A strong number is a number equal to the sum of the factorials of its own digits — printing them in a range means checking every candidate one by one.
Given a range of numbers, print every strong number it contains.
Java Program
public class StrongRange {
static int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
static boolean isStrong(int num) {
int original = num;
int sum = 0;
while (num > 0) {
sum += factorial(num % 10); // factorial of the last digit
num /= 10;
}
return sum == original;
}
public static void main(String[] args) {
StringBuilder result = new StringBuilder();
for (int i = 1; i <= 50000; i++) {
if (isStrong(i)) { // reuse the single-number check for every candidate
if (result.length() > 0) result.append(", ");
result.append(i);
}
}
System.out.println("Strong numbers: " + result);
}
}Output
Core Logic
Testing every number in the range with the same digit-factorial-sum check used to test a single number finds every strong number at once.
- 1
isStrong(n)is the single-number check, pulled out into its own method so it can be reused for every candidate. - 2The main loop tries every number from
1to50000, callingisStrong()on each. - 3A number that passes the check is appended to the result, separated by commas.
- 41 and 2 both qualify trivially, since a single digit's factorial applied to a one-digit number equals the digit itself.
Key Point: Strong numbers are far rarer than Armstrong numbers in the same range, since 9! = 362880 is enormous compared to 9³ = 729 — most digit combinations overshoot the original number by a wide margin.
Why: Every one of the n candidates in the range gets its own O(d) digit check, where d is that number's digit count.
Key Concepts
Approach 2: Java 8
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class StrongRangeStream {
static boolean isStrong(int num) {
int[] factorials = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int sum = String.valueOf(num).chars()
.map(c -> factorials[c - '0'])
.sum();
return sum == num;
}
public static void main(String[] args) {
// Keeps only the numbers that pass the strong-number check, then joins them
String result = IntStream.rangeClosed(1, 50000)
.filter(StrongRangeStream::isStrong)
.mapToObj(String::valueOf)
.collect(Collectors.joining(", "));
System.out.println("Strong numbers: " + result);
}
}
Output
Core Logic
The same range scan can filter a stream of candidate numbers down to just the strong ones, then join the survivors.
- 1
IntStream.rangeClosed(1, 50000)generates every candidate number in the range. - 2
.filter(StrongRangeStream::isStrong)keeps only the numbers that pass the strong-number check, reusing the same helper method as a method reference. - 3
.mapToObj(String::valueOf)converts each surviving number into aString. - 4
.collect(Collectors.joining(", "))joins them into the final comma-separated result.
Key Point: Scanning up to 50000 with a per-number digit check is still fast in practice, since the digit count of any number in that range never exceeds five.
Why: The stream still checks every candidate's digits, and Collectors.joining() builds a result string holding every strong number found.