완전수란 무엇인가?
완전수(Perfect Number)는 자기 자신을 제외한 모든 양의 약수의 합이 자기 자신과 같은 양의 정수를 말합니다. 여기서 약수(divisor)란 어떤 정수 x를 나누어 떨어지게 하는 정수를 의미합니다.
예를 들어 다음과 같습니다.
28은 완전수입니다. 28 = 1 + 2 + 4 + 7 + 14
이 글에서는 숫자 n을 입력받아 n이 완전수인지 아닌지를 판별하는 자바스크립트 함수를 작성해 보겠습니다.
구현 예제
const num = 28;
const checkPerfectNumber = (num = 1) => {
if(num === 1) {
return false;
};
let sum = 1;
for(let i = 2; i <= Math.floor(Math.sqrt(num)); i++){
if(num % i === 0) {
sum = sum + i + num / i; if(sum > num) {
return false;
}
};
};
return sum === num;
};
console.log(checkPerfectNumber(num));출력 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
true
코드 동작 원리
이 알고리즘이 효율적으로 동작하는 이유는 다음과 같습니다.
1. 1은 미리 제외
1은 자기 자신을 제외한 약수의 합이 0이 되므로 완전수가 될 수 없습니다. 따라서 입력값이 1이면 즉시 false를 반환합니다.
2. 약수의 대칭성 활용
약수는 항상 쌍으로 존재합니다. 예를 들어 28의 경우 2 × 14처럼 하나의 약수 i를 찾으면 짝이 되는 약수 num / i도 함께 구할 수 있습니다. 이 덕분에 2부터 √num까지만 반복하면 모든 약수를 확인할 수 있어 시간 복잡도가 O(√n)으로 크게 줄어듭니다.
3. 조기 종료(Early Exit)
반복 도중 약수의 합이 이미 num을 초과하면 더 이상 완전수일 가능성이 없으므로 즉시 false를 반환해 불필요한 연산을 줄입니다.
4. 최종 비교
루프가 끝난 후 누적된 합 sum이 num과 정확히 같다면 해당 숫자는 완전수이므로 true를 반환합니다.
참고로 완전수는 매우 드문 숫자로, 6, 28, 496, 8128 등이 알려져 있습니다. 위 함수에 6이나 496을 넣어도 true가 출력되는 것을 직접 확인해 볼 수 있습니다.