⚙️ 알고리즘/프로그래머스

[Swift] 프로그래머스 코딩테스트 입문 - 구슬을 나누는 경우의 수

dev_zoe 2023. 1. 18. 01:20
반응형

문제 설명

머쓱이는 구슬을 친구들에게 나누어주려고 합니다. 구슬은 모두 다르게 생겼습니다. 머쓱이가 갖고 있는 구슬의 개수 balls와 친구들에게 나누어 줄 구슬 개수 share이 매개변수로 주어질 때, balls개의 구슬 중 share개의 구슬을 고르는 가능한 모든 경우의 수를 return 하는 solution 함수를 완성해주세요.

 
제한사항
  • 1 ≤ balls ≤ 30
  • 1 ≤ share ≤ 30
  • 구슬을 고르는 순서는 고려하지 않습니다.
  • share  balls

 

입출력 예
balls                                                       share                                                     result

 

3 2 3
5 3 10

 

입출력 예 설명

입출력 예 #1

  • 서로 다른 구슬 3개 중 2개를 고르는 경우의 수는 3입니다. 

입출력 예 #2

  • 서로 다른 구슬 5개 중 3개를 고르는 경우의 수는 10입니다.
Hint
  • 서로 다른 n개 중 m개를 뽑는 경우의 수 공식은 다음과 같습니다. 

 

내가 푼 풀이 1 (오답)

import Foundation

func solution(_ balls:Int, _ share:Int) -> Int {
    var n = 1
    var m = 1
    
    var i = balls
    
    while i>=balls-share+1 {
        n*=i
        i-=1
    }
    i = 1
    
    while i<=share {
        m*=i
        i+=1
    }
    
    return Int(n/m)
}

계속 몇가지 케이스에서 core dump 오류가 떠서 (보통 무언가의 범위를 벗어났을 때 뜸) 여러 다른 풀이 사례들을 찾아봤다.

다른 풀이를 보니, 만약에 27/3와 같다면 27의 팩토리얼이 int 범위를 벗어나는 수이기 때문에 core dump 에러가 뜨는것으로 추측되었다.

따라서 아얘 계산까지 하는 부분을 Double 자료형으로 처리하고, 마지막에 반환할때만 int로 변환해주기로 했다.

 

 

내가 푼 풀이 2 (오답)

import Foundation

func solution(_ balls:Int, _ share:Int) -> Int {
    var n = Double(1)
    var m = Double(1)

    var i = Double(balls)

    while i>=Double(balls-share+1) {
        n*=i
        i-=1.0
    }
    i = 1.0

    while i<=Double(share) {
        m*=i
        i+=1.0
    }

    return Int(Double(n/m))
}

이렇게 냈더니 테스트케이스 34번만 실패로 떴었다 ㅠㅠ

결국 코린이인 나는 다른분의 풀이를 보면서 질문해볼수밖에 없었는데,, double을 int로 변환할때 부동소수점이 문제가 된다고 한다.

예를 들어, 계산한 값이 511.999999999999999 이런 부동소수점일 경우에 int로 변환하면, 소수점을 아얘 버리기 때문에 512가 아닌 511이 정답이 되므로 이런 경우의 테스트케이스가 통과하지 못한듯 하다.

 

여기서 깨달은 점은, 수식의 경우 소수점이 나오는 경우를 대비해 올림할건지 버림할건지 등에 대한 테스트케이스도 따져봐야함을 깨달았다.

 

그래서 내가 제출해서 통과한 정답은..?!!

func solution(_ balls:Int, _ share:Int) -> Int {
    var n = Double(1)
    var m = Double(1)

    var i = Double(balls)

    while i>=Double(balls-share+1) {
        n*=i
        i-=1.0
    }
    i = 1.0

    while i<=Double(share) {
        m*=i
        i+=1.0
    }

    return Int(round(Double(n/m)))
}

 

반응형