이번 글에서는 Math.sqrt() 같은 수학 라이브러리 함수를 전혀 사용하지 않고, 주어진 숫자가 완전제곱수(perfect square)인지 판별하는 JavaScript 함수를 작성해 보겠습니다. 함수는 숫자를 인자로 받아, 해당 숫자가 완전제곱수라면 true, 아니라면 false를 반환해야 합니다.
완전제곱수란?
완전제곱수는 어떤 정수를 제곱했을 때 얻어지는 수를 말합니다. 예를 들어 다음과 같은 수들이 완전제곱수에 해당합니다.
4 (=2²), 16 (=4²), 81 (=9²), 441 (=21²), 256 (=16²), 729 (=27²), 9801 (=99²)
구현 아이디어
제곱근 함수를 쓸 수 없다면, 가장 직관적인 방법은 1부터 시작하는 정수를 하나씩 늘려가며 그 제곱이 목표 숫자와 일치하는지 확인하는 것입니다. 어떤 정수의 제곱이 목표 숫자보다 커지는 시점까지도 일치하지 않았다면, 그 숫자는 완전제곱수가 아닙니다.
코드 구현
const num = 81;
const isPerfectSquare = num => {
let ind = 1;
while(ind * ind <= num){
if(ind * ind !== num){
ind++;
continue;
};
return true;
};
return false;
};
console.log(isPerfectSquare(81));
console.log(isPerfectSquare(9801));
console.log(isPerfectSquare(99));
console.log(isPerfectSquare(441));
console.log(isPerfectSquare(7648));코드 설명
함수 내부에서는 변수 ind를 1로 초기화한 뒤, 반복문을 돌며 ind * ind(현재 정수의 제곱)가 입력값 num 이하인 동안 계속 검사합니다.
ind * ind가num과 같으면 해당 숫자는 완전제곱수이므로 즉시true를 반환합니다.- 같지 않으면
ind를 1 증가시키고 다음 후보를 검사합니다. ind * ind가num을 초과하면 반복문이 종료되고, 끝까지 일치하는 값이 없었으므로false를 반환합니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
true true false true false
81(=9²), 9801(=99²), 441(=21²)은 완전제곱수이므로 true가 출력되고, 99와 7648은 어떤 정수의 제곱으로 표현할 수 없기 때문에 false가 출력됩니다.
참고: 성능 개선 여지
위 방식은 이해하기 쉽지만, 숫자가 클 경우 1부터 차례대로 검사하므로 시간 복잡도가 O(√n)입니다. 더 빠른 처리가 필요하다면 이진 탐색(binary search)을 활용해 탐색 범위를 절반씩 줄여가는 방법으로 최적화할 수 있습니다. 또한 음수는 완전제곱수가 될 수 없으므로, 실무 코드에서는 입력값이 0 이상인지 먼저 확인하는 방어 로직을 추가하는 것이 좋습니다.