Coding Test/Codility
10. 소수와 합성수 (Prime and Composite Numbers) Codility Lesson 한국어 정리본 (JavaScript ver.)
chamroro
2025. 3. 2. 16:17
소수(Prime Number)와 합성수(Composite Number)
소수(Prime Number) 는 1보다 크고, 자기 자신과 1을 제외한 약수가 없는 수 를 의미한다.
합성수(Composite Number) 는 1과 자기 자신 이외에도 다른 약수를 가지는 수 를 의미한다.
예를 들어, 2, 3, 5, 7, 11, 13 등은 소수이며, 4, 6, 8, 9, 10 등은 합성수이다.
1. O(√n) 시간 복잡도의 약수 개수 구하기
n의 약수를 찾는 기본적인 방법은 1부터 n까지 모든 수를 확인하는 것 이다. 하지만 n의 약수는 대칭성을 가지므로, √n 까지만 탐색해도 전체 약수를 구할 수 있다.
JavaScript 코드:
function countDivisors(n) {
let count = 0;
let i = 1;
while (i * i < n) {
if (n % i === 0) {
count += 2; // i와 n/i 두 개의 약수 추가
}
i++;
}
if (i * i === n) {
count += 1; // 제곱수일 경우 중복 제거
}
return count;
}
시간 복잡도: O(√n)
2. O(√n) 시간 복잡도의 소수 판별
소수인지 확인하는 방법:
- 2부터 n-1까지 모든 숫자로 나누어 보면 O(n) 시간이 걸림.
- √n까지만 검사하면 O(√n)으로 최적화 가능
JavaScript 코드:
function isPrime(n) {
if (n < 2) return false;
let i = 2;
while (i * i <= n) {
if (n % i === 0) return false;
i++;
}
return true;
}
시간 복잡도: O(√n)
3. 동전 뒤집기 문제 (Coin Flipping Problem)
n개의 동전이 일렬로 놓여 있고, 초기에는 모두 앞면(Heads)이다.
- i번째 사람이 배수 위치의 동전을 뒤집는다. (예: i = 3이면 3, 6, 9, ...을 뒤집음)
- 최종적으로 뒷면(Tails)이 보이는 동전의 개수를 구하는 문제.
O(n log n) 해결법 (시뮬레이션)
function countTails(n) {
let result = 0;
let coin = new Array(n + 1).fill(0);
for (let i = 1; i <= n; i++) {
let k = i;
while (k <= n) {
coin[k] = (coin[k] + 1) % 2;
k += i;
}
result += coin[i];
}
return result;
}
시간 복잡도: O(n log n)
O(√n) 해결법 (수학적 최적화)
뒤집힌 횟수가 홀수인 동전 만 뒷면을 보이게 된다. 이는 약수의 개수가 홀수인 경우인데, 제곱수만 홀수 개의 약수를 가진다. 즉, 1, 4, 9, 16, ...의 개수를 찾으면 된다.
function countTailsOptimized(n) {
return Math.floor(Math.sqrt(n));
}
시간 복잡도: O(1) (제곱근 계산)
반응형