Check Number Spy in Java
Problem
A Spy number is a number where the sum of its digits equals the product of its digits.
Given a number, determine whether it is a Spy number.
Java Program
public class SpyNumberCheck {
public static void main(String[] args) {
int n = 1124;
int original = n;
int sum = 0;
int product = 1;
while (n > 0) {
int digit = n % 10; // extract once, update both totals from the same digit
sum += digit;
product *= digit;
n /= 10;
}
System.out.println(original + " is a Spy number: " + (sum == product));
}
}Output
Core Logic
Extracting each digit once and updating a running sum and a running product together, in the same pass, checks both totals without looping over the digits twice.
- 1A single while loop peels off each digit of
nwith% 10and/= 10. - 2Each digit is added into
sumand multiplied intoproductin the same iteration. - 3
productstarts at1, the multiplicative identity, so the first digit multiplies in cleanly. - 4Once every digit has been processed,
sumandproductare compared directly.
1124, the digits 1, 1, 2, 4 sum to 8 and multiply to 8 as well, so they match.Key Point: Updating both totals inside the same loop, rather than summing in one pass and multiplying in another, means every digit is only extracted once.
Why: A single pass extracts each digit once, updating both accumulators together, so the digit count is the only thing the cost scales with.
Key Concepts
Approach 2: Java 8
public class SpyNumberCheckStream {
public static void main(String[] args) {
int n = 1124;
int original = n;
// A stream can only be consumed once, so sum and product each need their own digit stream
int sum = String.valueOf(n).chars().map(c -> c - '0').sum();
int product = String.valueOf(n).chars().map(c -> c - '0').reduce(1, (a, b) -> a * b);
System.out.println(original + " is a Spy number: " + (sum == product));
}
}
Output
Core Logic
Since a single stream can only be consumed once, summing and multiplying the digits with streams means building two separate digit streams instead of extracting each digit once for both totals.
- 1
String.valueOf(n).chars().map(c -> c - '0')builds a stream of digit values — this expression is used twice, once for each total, since a stream can't be reused after a terminal operation runs. - 2
.sum()on the first stream totals the digits. - 3
.reduce(1, (a, b) -> a * b)on the second stream multiplies them together, starting from1as the multiplicative identity —IntStreamhas no built-inproduct(). - 4The two independently-computed totals are compared, same as the manual version.
1124, one digit stream sums to 8 and a second, separately built digit stream multiplies to 8 as well, so they match.Key Point: This genuinely costs more than the manual loop — extracting the digits twice, once per stream, instead of updating both totals from a single pass — because a stream offers no way to fork one pass into two independent reductions without a custom collector.
Why: Each stream still visits all d digits, so building two streams doubles the digit extractions compared to the manual single-pass loop, though both remain linear in d.