JavaScript Program to Find Perfect Number
function isPerfect(num) { let sum = 0; for (let i = 1; i <= num / 2; i++) { if (num % i === 0) sum += i; } return sum === num; }.Examples
How to Think About It
Algorithm
Code
function isPerfect(num) { let sum = 0; for (let i = 1; i <= num / 2; i++) { if (num % i === 0) { sum += i; } } return sum === num; } const number = 28; if (isPerfect(number)) { console.log(number + ' is a perfect number'); } else { console.log(number + ' is not a perfect number'); }
Dry Run
Let's trace the number 6 through the code to see how it checks if 6 is perfect.
Initialize sum
sum = 0
Check divisors from 1 to 3
i = 1 to 3
Add divisors that divide 6 evenly
1 divides 6, sum = 0 + 1 = 1; 2 divides 6, sum = 1 + 2 = 3; 3 divides 6, sum = 3 + 3 = 6
Compare sum with number
sum = 6, number = 6, sum === number is true
| i | num % i | sum |
|---|---|---|
| 1 | 6 % 1 = 0 | 1 |
| 2 | 6 % 2 = 0 | 3 |
| 3 | 6 % 3 = 0 | 6 |
| 4 | 6 % 4 = 2 | 6 |
| 5 | 6 % 5 = 1 | 6 |
Why This Works
Step 1: Find divisors
The code finds all numbers less than the input that divide it evenly using num % i === 0.
Step 2: Sum divisors
It adds these divisors to a sum to get the total of all proper divisors.
Step 3: Compare sum to number
If the sum equals the original number, the number is perfect, so the function returns true.
Alternative Approaches
function isPerfect(num) { let sum = 0; for (let i = 1; i <= num / 2; i++) { if (num % i === 0) sum += i; } return sum === num; } console.log(isPerfect(28) ? '28 is a perfect number' : '28 is not a perfect number');
function sumDivisors(num, i = 1) { if (i > num / 2) return 0; return (num % i === 0 ? i : 0) + sumDivisors(num, i + 1); } function isPerfect(num) { return sumDivisors(num) === num; } console.log(isPerfect(6) ? '6 is a perfect number' : '6 is not a perfect number');
Complexity: O(n) time, O(1) space
Time Complexity
The loop runs from 1 to n-1 (or n/2 in the optimized version), so it takes linear time proportional to the input number.
Space Complexity
The program uses a fixed amount of extra space for variables, so space complexity is constant.
Which Approach is Fastest?
Checking divisors only up to half the number is faster than checking all numbers less than n. Recursion is less efficient and uses more stack space.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Check all divisors up to n-1 | O(n) | O(1) | Simple understanding |
| Check divisors up to n/2 | O(n/2) ~ O(n) | O(1) | Better performance |
| Recursive divisor sum | O(n) | O(n) | Elegant but less efficient |