프로그래머스 3-26 TIL

Seunggyu Jung·2023년 3월 26일
0

구슬을 나누는 경우의 수

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

내 풀이

function solution(balls, share) {
    let Up = 1;
    let Front = 1;
    let End = 1;
    for (let i = balls; i >= 1; i--) {  
        Up = Up * i;
    }
    for (let j = balls - share; j >= 1; j--) {
        Front = Front * j;
    }
    for (let h = share; h >= 1; h--) {
        End = End * h;
    }
    return balls - share === 0 ? 1 : Math.round(Up / (Front * End)) ;  
}

해설

해당 문제는 필자가 1회독 할 당시 정답을 보고 해결했기에 어느정도 풀 수 있었음

  • 1단계. 해당 문제는 팩토리얼을 풀 수 있는지에 대해 묻는 문제라는 것을 파악
  • 2단계. 분자와 분모에 각각 변수를 선언하여 팩토리얼을 계산
    여기서 중요한점은 반복문을 사용할때, 오름차순으로 팩토리얼을 계산하면 오류가 발생함. 따라서 이러한 경우에는 내림차순으로 변경해볼 것
  • 3단계. balls - share === 0 , 즉, 공의 개수와 나눌 개수가 같은 경우에는 경우의 수가 1가지 밖에 없기에 해당 경우를 추가해줌
  • 4단계. 컴퓨터의 특성상, 소숫점계산에서 0.1 + 0.2 != 0.3 이며 0.1 + 0.2 === 0.30000000000000004 이다. 이는 컴퓨터는 10진법이 아닌 2진법으로 계산을 하기 때문. 이 경우, Math.round()로 반올림처리 해주면 오류가 발생하지 않는다.

마무리

  • 반복문의 내림차순과 오름차순의 차이점이 발생하는 이유에 대해 스터디에서 논의 해볼만하다고 생각한다.
  • 또한 4단계에서 분모에 Math.round()을 해야하는 경우를 찾아내는 방법에 대해서도 논의해봐도 좋을 것이라 생각한다. 왜냐하면, 문제를 풀며 언제, 어디서 오류가 발생했는지 다 찾는 것은 불가능하기 때문이다.
profile
감동을 주고픈 개발자(준비생)

0개의 댓글