-
[프로그래머스 / JS] Lv.0 구슬을 나누는 경우의 수Algorithm/프로그래머스 2022. 12. 13. 17:53반응형
문제 설명
머쓱이는 구슬을 친구들에게 나누어주려고 합니다. 구슬은 모두 다르게 생겼습니다. 머쓱이가 갖고 있는 구슬의 개수 balls와 친구들에게 나누어 줄 구슬 개수 share이 매개변수로 주어질 때, balls개의 구슬 중 share개의 구슬을 고르는 가능한 모든 경우의 수를 return 하는 solution 함수를 완성해 주세요.
제한사항
- 1 ≤ balls ≤ 30
- 1 ≤ share ≤ 30
- 구슬을 고르는 순서는 고려하지 않습니다.
- share ≤ balls
풀이
function solution(balls, share) { if (share === 0) return 1 return factorial(balls) / (factorial(balls - share) * factorial(share)) } function factorial(n) { let re = BigInt(1) for (let result = 2; result <= n; result++) { re *= BigInt(result) } return re }
사고과정
- 재귀를 이용해 팩토리얼 함수를 선언한다
- 팩토리얼 함수를 이용해 조합 공식을 풀면 되겠다
- 에러가 뜨네?
- js 특성상 수가 너무 커 int 범위에서 벗어날 경우 오류가 발생할 수 있다.
- 보다 큰 수를 담을 수 있는 bigint를 사용하자
평가
function solution(balls, share) { if (share === 0) return 1 return Math.floor(factorial(balls) / (factorial(balls - share) * factorial(share))) } function factorial(n) { if (n <= 1) return 1 return n * factorial(n - 1) }
const 팩토리얼 = (num) => num === 0 ? 1 : num * 팩토리얼(num - 1) function solution(balls, share) { return Math.round(팩토리얼(balls) / 팩토리얼(balls - share) / 팩토리얼(share)) }
위 첫 번째 코드는 사고과정 (2)에서 작성한 코드이며 큰 수에 대해 오류가 발생했다. js 정수형이 감당할 수 없는 큰 수로 인해 문제가 발생함을 깨달았고 풀이에서와 같은 코드로 고쳤다. 두 번째 코드는 다른 사람의 풀이 중 간략한 풀이를 가져온 것이다. factorial 함수의 구조도 거의 동일하다고 볼 수 있고 차이점은 나와 달리 Math.round를 적용한 것뿐이다.
내가 생각하기에 조합 연산 결과가 소수점 아래 값을 가진다면 내림하는 게 맞는데 왜 반올림하는 게 옳은 정답을 내놓는 것일까? 이 부분은 정확한 정답을 아직 찾지 못했으며 조금 더 가까운 정수로 변환해주는 만큼 정답으로 처리하는 것인가 짐작만 하고 있다.
개선점
알게된점
- js에선 큰 수로 인해 오류가 발생할 수 있다.
- js의 큰 수에 대해선 bigint()로 대처 가능하며 bigint는 bigint끼리만 연산 가능하다. 단, 비교는 상관없다.
반응형'Algorithm > 프로그래머스' 카테고리의 다른 글
[프로그래머스 / JS] Lv.0 최빈값 구하기 (0) 2022.12.15 [프로그래머스 / JS] Lv.0 외계행성의 나이 (0) 2022.12.13 [프로그래머스 / JS] Lv. 0 저주의 숫자 3 (0) 2022.12.13 [프로그래머스 / JS] Lv.0 평행 (0) 2022.12.12 [프로그래머스 / JS] LV.0 겹치는 선분의 길이 (0) 2022.12.12