[프로그래머스] 구슬을 나누는 경우의 수(조합 구하기)
문제 설명
머쓱이는 구슬을 친구들에게 나누어주려고 합니다. 구슬은 모두 다르게 생겼습니다. 머쓱이가 갖고 있는 구슬의 개수 balls와 친구들에게 나누어 줄 구슬 개수 share이 매개변수로 주어질 때, balls개의 구슬 중 share개의 구슬을 고르는 가능한 모든 경우의 수를 return 하는 solution 함수를 완성해주세요.
제한사항
- 1 ≤ balls ≤ 30
- 1 ≤ share ≤ 30
- 구슬을 고르는 순서는 고려하지 않습니다.
- share ≤ balls

조합을 구하는 문제이다.
조합을 구하는 식은 n!/(n-r)!r! 이다.
* 조합 : 서로 다른 n개에서 순서를 고려하지 않고 서로 다른 r(0<=r<=n)개를 택하는 것.
나의 풀이 1. 오답?
def solution(balls, share):
def fac(n):
for i in range(2,n):
n=n*i
return n
return fac(balls)//(fac(balls-share)*fac(share))
먼저 조합을 구하는 식에서 팩토리얼이 많이 쓰이므로 함수로 하나 만들어 넣어 주었다.
코드 실행해서 테스트케이스 2개는 잘 돌아가길래 오 됐다~ 했는데
막상 제출해보니 테스트 2, 3, 24에서 런타임 에러가 났다,,,
왜 오류가 난 걸까 하고 생각해보니, 팩토리얼 함수 짤 때
0인 경우를 빼지 않아서 그런 것 같았다...
balls=share일 경우 b를 구할 때 0으로 곱연산을 해버리기 때문에 오류가 났다!
이런 기초적인 실수를 하다니.
그 부분을 해결하기 위해 아래와 같이 n이 0일 경우 1을 반환하도록 처리해주었다.
나의 풀이 2. 정답
def solution(balls, share):
def fac(n):
if n==0:
return 1
else:
for i in range(2,n):
n=n*i
return n
return fac(balls)//(fac(balls-share)*fac(share))
이제 잘 돌아간다.
다른 풀이
import math
def solution(balls, share):
return math.comb(balls, share)
사실 math모듈을 채택한다면 위와 같이 매우 간단하게 해결 가능하다.
math.factorial(n)을 활용하여 for문 없이 팩토리얼을 구할 수 있지만
이 풀이에서는 아예 math.comb(n,r)를 활용하여 조합 결과를 한큐에 구해버렸다...
웬만하면 간단한 문제에서는 모듈 안 쓰고 직접 짜서 해결하려고 하는 편이긴 한데...
모듈로 조합까지 그냥 구할 수 있는 줄은 몰랐다...
나중에 검색해보다가 알게 되었다. 눈물바다.