문제 개요
두 개의 숫자, 예를 들어 a와 b를 입력받아 두 수 사이에 존재하는 모든 소수를 찾고, 그 합계를 구하는 JavaScript 함수를 작성해 보겠습니다. 만약 a와 b 자체가 소수라면 이들 역시 계산에 포함해야 합니다.
이 문제는 크게 두 단계로 나누어 해결할 수 있습니다.
1단계: 소수 판별 함수 만들기
먼저 임의의 숫자가 소수인지 아닌지를 판별하는 isPrime 함수가 필요합니다. 1은 소수가 아니며, 2는 유일한 짝수 소수입니다. 그 외의 숫자는 2부터 자기 자신보다 작은 수까지 차례대로 나누어 떨어지는지 검사하면 됩니다.
2단계: 범위 내 소수 찾기
다음으로 primeBetween 함수를 통해 a부터 b까지 한 칸씩 증가시키면서 각 숫자가 소수인지 확인하고, 소수라면 결과 배열에 담습니다.
예제 코드
다음은 전체 구현 코드입니다.
const num1 = 45;
const num2 = 345;
// 소수 여부를 판별하는 함수
const isPrime = n => {
if (n === 1) {
return false;
} else if (n === 2) {
return true;
} else {
for (let x = 2; x < n; x++) {
if (n % x === 0) {
return false;
}
}
return true;
}
};
// a부터 b 사이의 소수를 배열로 반환하는 함수
const primeBetween = (a, b) => {
const res = [];
while (a <= b) {
if (isPrime(a)) {
res.push(a);
}
a++;
}
return res;
};
console.log(primeBetween(num1, num2));출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[ 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337 ]
코드 설명
isPrime 함수는 인자로 받은 숫자 n이 1이면 false를, 2이면 true를 반환합니다. 그 외의 경우에는 2부터 n-1까지의 모든 정수로 나누어 보고, 하나라도 나누어 떨어지면 약수가 존재한다는 뜻이므로 false를 반환합니다. 끝까지 나누어 떨어지는 수가 없다면 소수이므로 true를 반환합니다.
primeBetween 함수는 while 루프를 사용해 a가 b보다 작거나 같은 동안 매번 isPrime으로 소수 여부를 검사하고, 소수인 경우에만 배열에 추가한 뒤 a를 1씩 증가시킵니다. 덕분에 시작 값과 끝 값이 소수인 경우에도 자동으로 포함됩니다.
소수의 합계 구하기
찾아낸 소수들의 합계가 필요하다면 배열 메서드인 reduce()를 활용하면 간단합니다.
const sum = primeBetween(num1, num2).reduce((acc, cur) => acc + cur, 0); console.log(sum); // 9910
45부터 345 사이의 소수는 총 54개이며, 이들의 합은 9910입니다.
성능 최적화 팁
현재 isPrime 함수는 2부터 n-1까지 모두 검사하기 때문에 숫자가 커지면 속도가 느려집니다. 소수가 아니라면 반드시 √n 이하의 약수를 가진다는 성질을 이용해, 검사 범위를 제곱근까지만 줄이면 실행 속도를 크게 향상시킬 수 있습니다.
const isPrime = n => {
if (n < 2) return false;
for (let x = 2; x * x <= n; x++) {
if (n % x === 0) return false;
}
return true;
};