본문 바로가기

Algorithm/문제풀이

Codility Lesson10 - CountFactors

🔍 문제


 

 

CountFactors coding task - Learn to Code - Codility

Count factors of given number n.

app.codility.com

 

✏️ 풀이 - JS


첫 번째 풀이는 어렸을 때 수학 시간에 배운 어떤 수의 약수 개수 구하기가 생각나서 그 방식으로 풀어 보았다.
N을 소인수 분해한 후, 각 소인수의 지수+1을 해준 후 곱한 수를 반환하였다. 정확도는 100%가 나왔지만 문제는 performance에서 timeout error가 발생하였다. 만약 매우 큰 소수가 N(ex. 780291637)으로 들어올 경우 while문에서 i++를 해가면서 i가 N이 될 때까지 매우 오랜 시간이 걸렸다. 또, 정수 타입 중 가장 큰 값이 N으로 들어오면 시간 초과가 발생하였다. 따라서 다른 방법으로 풀어보기로 했다.

function solution(N) {
    let map = new Map();
    let i = 2;

    while(true) {
        if(N === 1) break;
        if(N % i === 0) {
            if(!map.has(i)) map.set(i, 0);
            map.set(i, map.get(i)+1);
            N = N / i;
        } else {
            i++;
        }
    }

    let factorCnt = 1;

    for(let value of map.values()) {
        factorCnt *= value+1;
    }

    return factorCnt
}

따라서 두번째 풀이는 아래와 같이 풀어보았다. 예를 들어, N = 100이라면, 1, 2, 4, 5, 10(=Math.sqrt(100)), 20, 25, 50, 100이 약수이다.
만약 Math.sqrt(N)이 정수라면, Math.sqrt(N)가 N의 약수가 되며, 나머지 약수들은 Math.sqrt(N)을 기준으로 앞 뒤로 짝을 이루고 있다.
따라서 Math.sqrt(N)(= N의 제곱근)을 기준으로 약수의 개수를 구한 후, 그 개수에 *2를 해준다. 그리고 Math.sqrt(N)이 정수라면 Math.sqrt(N)자체가 N의 약수가 되기 때문에 +1을 해주었다. 시간 복잡도는 O(sqrt(N))가 나왔고 이번에는 정확도, performance 모두 통과하였다.

function solution(N) {
    if (N === 1) return 1;

    let factorCnt = 1;

    for(let i = 2; i < Math.sqrt(N); i++) {
        if(N % i === 0) {
            factorCnt++;
        }
    }

    factorCnt = factorCnt * 2;

    if(Math.sqrt(N) % 1 === 0) factorCnt++;

    return factorCnt;
}

'Algorithm > 문제풀이' 카테고리의 다른 글

Codility Lesson10 - Peaks  (0) 2019.08.17
Codility Lesson10 - MinPerimeterRectangle  (0) 2019.08.16
Codility Lesson9 - MaxDoubleSliceSum  (0) 2019.08.14
Codility Lesson9 - MaxSliceSum  (0) 2019.08.14
Codility Lesson9 - MaxProfit  (2) 2019.08.13