한 걸음씩

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

Programmers

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

winter17 2023. 7. 9. 11:24

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

풀이 과정

function solution(balls, share) {
	// 팩토리얼 재귀로 풀기
    function factorial(num){
        if (num === 0 || num === 1){
            return 1
        }else{
            return num * factorial(num-1)
        }
    }
    if (balls < share){
        return 0
    }else{
        // 계산 결과가 실수일 수 있으므로 소수점 이하를 반올림하여 정수로 반환하는 함수
        return Math.round(factorial(balls) / (factorial(balls - share) * factorial(share)))
    }
}

완전 수학문제인데 문제 힌트가 "서로 다른 n개 중 m개를 뽑는 경우의 수 공식 : n! / ((n-m)! * m!)"

팩토리얼을 재귀방식으로 풀면 0과 1인 경우는 1을 반환하고 그 이외의 수는 num * factorial(num - 1)을 반환한다.

5! 를 구해야 할 때의 과정은 다음과 같다

factorial(5) = 5 * factorial(4) → 5 * 24 = 120

factorial(4) = 4 * factorial(3) → 4 * 6 = 24

factorial(3) = 3 * factorial(2) → 3 * 2 = 6

factorial(2) = 2 * factorial(1) → 2 * 1 = 2

factorial(1) = 1

 

위의 과정까지 마쳤다면 조건문을 사용해서 한 번 더 걸러야 하는데 서로 다른 n개 중 m개를 뽑는 경우의 수에서 m이 n보다 크면 빈 집합을 선택하는 경우가 생길 수 있으므로 0을 반환해야 하고

공식을 사용하여 답을 도출할 경우에 Math.round를 사용하여 소수점 이하를 반올림하여 정수로 반환해야 통과된다.


리뷰

팩토리얼을 재귀로 푸는 방법을 구현해 본 적이 없어서 다른 사람 코드를 참고했는데 하나씩 손으로 과정을 그려가며 풀이해 보니까 이해를 하게 되었다. 

마지막에 답을 리턴하기 전 소수점을 반올림해야 하는데 그렇지 않으면 실수를 반환하게돼서 실패가 나온다.

이 문제는 완전 수학 문제라서 경우의 수가 약한 나에게는 어려운 문제였다...