프로그래밍/프로그래머스

[프로그래머스] 구슬을 나누는 경우의 수(조합 구하기)

서요서요 2022. 11. 17. 15:34

문제 설명

머쓱이는 구슬을 친구들에게 나누어주려고 합니다. 구슬은 모두 다르게 생겼습니다. 머쓱이가 갖고 있는 구슬의 개수 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)를 활용하여 조합 결과를 한큐에 구해버렸다...

 

웬만하면 간단한 문제에서는 모듈 안 쓰고 직접 짜서 해결하려고 하는 편이긴 한데...

모듈로 조합까지 그냥 구할 수 있는 줄은 몰랐다...

나중에 검색해보다가 알게 되었다. 눈물바다.