문제 소개
두 개의 숫자 m과 n으로 구성된 배열을 통해 범위를 지정받는 JavaScript 함수를 작성해야 합니다.
이 함수는 m부터 n까지(단, 1 ≤ m ≤ n)의 정수 중에서, 해당 정수의 모든 약수를 각각 제곱한 뒤 그 합을 계산했을 때 결과값이 완전제곱수(perfect square)가 되는 수들을 찾아야 합니다.
함수의 반환값은 여러 개의 하위 배열을 담은 배열입니다. 각 하위 배열은 두 개의 요소로 구성됩니다. 첫 번째 요소는 조건을 만족하는 정수이고, 두 번째 요소는 그 정수의 제곱된 약수들의 합입니다.
코드 구현
다음은 위 문제를 해결하는 코드입니다 −
const range = [1, 500];
const listSquared = ([m, n]) => {
const res = [];
for (let i = m; i <= n; ++i) {
let sum = getDivisors(i).reduce((sum, n) => sum + n * n, 0);
let ok = Number.isInteger(Math.sqrt(sum));
if (ok) {
res.push([i, sum]);
}
}
return res;
}
function getDivisors (n) {
const divisors = [];
for (let i = 1; i <= n / 2; ++i) {
if (n % i) {
continue;
}
divisors.push(i);
}
return divisors.concat([n]);
}
console.log(listSquared(range));
출력 결과
[ [ 1, 1 ], [ 42, 2500 ], [ 246, 84100 ], [ 287, 84100 ] ]
코드 동작 원리
getDivisors 함수는 주어진 숫자 n의 모든 약수를 구하는 역할을 합니다. 1부터 n/2까지 반복하면서 나누어 떨어지는 수를 약수 배열에 추가하고, 마지막에 자기 자신(n)도 포함시킵니다.
listSquared 함수는 지정된 범위 내의 각 정수에 대해 다음 과정을 수행합니다.
먼저 getDivisors로 약수 목록을 구한 뒤, reduce 메서드를 사용해 각 약수를 제곱하고 모두 더합니다. 그다음 Math.sqrt(sum)의 결과가 정수인지 Number.isInteger()로 확인하여 합이 완전제곱수인지 판별합니다. 조건을 만족하면 [숫자, 합] 형태의 쌍을 결과 배열에 추가합니다.
결과 검증 예시
출력 결과에서 42를 살펴보면, 42의 약수는 1, 2, 3, 6, 7, 14, 21, 42입니다. 이들을 각각 제곱하여 더하면 1 + 4 + 9 + 36 + 49 + 196 + 441 + 1764 = 2500이 되고, 2500은 50²이므로 완전제곱수입니다. 따라서 42는 조건을 만족하는 수입니다.