머쓱이는 구슬을 친구들에게 나누어주려고 합니다. 구슬은 모두 다르게 생겼습니다. 머쓱이가 갖고 있는 구슬의 개수 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()로 반올림처리 해주면 오류가 발생하지 않는다.
Math.round()
을 해야하는 경우를 찾아내는 방법에 대해서도 논의해봐도 좋을 것이라 생각한다. 왜냐하면, 문제를 풀며 언제, 어디서 오류가 발생했는지 다 찾는 것은 불가능하기 때문이다.