[프로그래머스] 구슬을 나누는 경우의 수.JS

ungnam·2023년 5월 31일

programmers level0

목록 보기
6/29

https://school.programmers.co.kr/learn/courses/30/lessons/120840

나의 풀이

function solution(balls, share) {
    let numer = 1;
    let denom = 1;
    
    for (let i = 0; i < share; i++) {
        numer *= balls - i;
        denom *= share - i;
    }
    
    return numer / denom;
}

문제를 보자마자 고등학교 때 배운 컴비네이션이 떠올랐다.
ballsshare 개를 고르는 경우의 수 = balls(balls1)...(ballsshare+1)/share(share1)...1balls * (balls - 1) * ... * (balls - share + 1) / share * (share - 1) * ... * 1

참고할 만한 풀이

function solution(balls, share) {
    function factorial(n) {
        if (n <= 1) return 1;
        else return n * factorial(n - 1);
    }  
    return factorial(balls) / (factorial(balls - share) * factorial(share))
}

✔ 컴비네이션 공식이 내가 계산할 때 썼던 방식과는 달랐다.
balls!/(ballsshare)!share!balls! / (balls - share)! * share!
✔ 재귀함수를 통해 팩토리얼을 구현할 수 있다.

채점 결과, 정확도 80%로 테스트에 통과하지 못했다.
코드 상에 문제가 없어서 다른 이유가 있는지 찾아보았다.

문제가 발생한 원인

JS의 경우 수가 Number.MAX_SAFE_INTEGER가 넘어가게 되면 위와 같이 값이 예상과는 다르게 출력된다. factorial(19)만 되어도 값이 Number.MAX_SAFE_INTEGER를 넘어가기 때문에 큰 수를 담을 수 있는 BigInt를 사용하면 정상적으로 값이 나오게 된다.

function solution(balls, share) {
    function factorial(n) {
        let acc = BigInt(1);
        let number = BigInt(n);

        while (number > 0) {
            acc *= number;
            number -= BigInt(1);
        }
        
        return acc;
    }  
    return factorial(balls) / (factorial(balls - share) * (factorial(share))
}

BigInt에 대한 자세한 설명 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/BigInt

profile
꾸준함을 잃지 말자.

0개의 댓글