-소수 판별 및 생성
-약수 개수 또는 약수 합 계산
-소인수 분해 (가장 작은 소인수 활용)
-특정 범위에서의 소수의 합 계산
-골드바흐의 추측(짝수를 두 소수의 합으로 표현)
-어떤 수가 합성수인지 판별
-오일러 피 함수(Euler’s Totient Function) 계산
각 숫자 i가 자신의 배수들에게만 영향을 미친다는 점을 이용해 약수 계산 가능
배수 관계 이용 : i는 반드시 i의 배수의 약수가 됨.
중복 계산 방지 : i의 배수만 처리하므로 효율적.
누적 계산 : 각 배수에 약수 개수를 누적.
function calculateDivisors(n) {
// 배열 인덱스와 숫자를 1:1 대응시키기 위해 n+1로 배열 생성
const divisors = Array(n + 1).fill(0);
for (let i = 1; i <= n; i++) {
// i의 배수(j+=i)에 대해 약수의 개수를 하나씩 증가
for (let j = i; j <= n; j += i) {
divisors[j]++;
}
}
return divisors;
}
console.log(calculateDivisors(6)); // [0, 1, 2, 2, 3, 2, 4]
소수 p의 배수는 모두 합성수임을 활용, 소수의 배수를 이용해 합성수를 빠르게 거르는 방식.
function sieve(n) {
const isPrime = Array(n + 1).fill(true);
isPrime[0] = isPrime[1] = false; // 0과 1은 소수가 아님
for (let i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (let j = i * i; j <= n; j += i) {
isPrime[j] = false; // i의 배수 제거
}
}
}
return isPrime;
}
const primes = sieve(10); // [false, false, true, true, false, true, false, true, false, false, false]
console.log(primes[7]); // true (7은 소수)
function solution(n) {
// 소수 판별을 위한 배열을 생성하고 모든 값을 false로 초기화
const isPrime = Array(n + 1).fill(false);
let compositeCount = 0;
for (let i = 2; i <= n; i++) {
if (!isPrime[i]) { // 소수라면
for (let j = i * 2; j <= n; j += i) {
isPrime[j] = true; // i의 배수들은 합성수(true)로 표시
}
}
}
// 합성수의 개수 카운트
for (let i = 2; i <= n; i++) {
if (isPrime[i]) {
compositeCount++;
}
}
return compositeCount;
}
i의 배수를 처리하면서 가장 작은 소인수를 기록, 소인수 분해를 빠르게 수행
function smallestPrimeFactors(n) {
const spf = Array(n + 1).fill(0); // spf[i]: i의 가장 작은 소인수
for (let i = 2; i <= n; i++) {
if (spf[i] === 0) { // 아직 처리되지 않은 경우
for (let j = i; j <= n; j += i) {
if (spf[j] === 0) spf[j] = i; // 가장 작은 소인수 기록
}
}
}
return spf;
}
console.log(smallestPrimeFactors(10)); // [0, 0, 2, 3, 2, 5, 2, 7, 2, 3, 2]