일반적으로 양의 정수 n의 팩토리얼(계승)은 n 이하의 모든 양의 정수를 곱한 값입니다. 예를 들어 factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 입니다.
서투른 팩토리얼(clumsy factorial)은 기존 팩토리얼에서 연산자만 바꾼 변형 문제입니다. 정수를 내림차순으로 배치하되, 곱셈 자리에 곱하기(*), 나누기(/), 더하기(+), 빼기(-)를 정해진 순서대로 순환하며 적용합니다.
예를 들어 clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1 과 같습니다. 단, 이 연산 역시 일반적인 산술 규칙을 따릅니다. 모든 곱셈과 나눗셈을 먼저 계산한 뒤 덧셈과 뺄셈을 처리하며, 곱셈·나눗셈끼리는 왼쪽에서 오른쪽 순서로 계산합니다.
JavaScript 코드 구현
이제 이 함수를 JavaScript로 작성해 보겠습니다.
const clumsy = num => {
let k=num;
let res = 0, temp=1, i=0;
while(k>0){
temp = k;
if(k-1>0){
temp*=(k-1);
}
if(k-2>0){
temp/=(k-2);
}
if(k-3>0){
if(k===num){
temp+=(k-3);
}else{
temp-=(k-3);
}
}
if(k===num){
res = temp;
}else{
res = res-temp;
}
k = k-4;
}
return res;
};
console.log(clumsy(4));
console.log(clumsy(10));
console.log(clumsy(16));
console.log(clumsy(5));
출력 결과
콘솔 실행 결과는 다음과 같습니다.
7 11.75 16.609523809523807 7.666666666666668
코드 동작 원리
이 알고리즘은 전체 식을 네 개의 숫자로 이루어진 그룹 단위로 나누어 처리합니다. 각 그룹은 "k * (k-1) / (k-2) ± (k-3)" 형태로 계산됩니다.
- 그룹별 계산: while 루프가 k를 4씩 줄여가며 각 그룹의 곱셈·나눗셈 결과를 temp 변수에 저장합니다.
- 첫 번째 그룹: 가장 앞의 그룹(k === num)은 최종 결과 res의 초기값이 되며, 네 번째 숫자가 존재하면 덧셈으로 연결합니다.
- 이후 그룹: 두 번째 그룹부터는 앞선 결과에서 해당 그룹의 값을 빼줍니다. 그룹 사이의 연산자가 항상 빼기(-)이기 때문입니다.
- 남은 숫자 처리: 마지막에 1~3개의 숫자만 남는 경우에도 조건문이 이를 자동으로 처리해 올바른 결과를 반환합니다.
참고로 JavaScript의 나눗셈 연산자(/)는 실수 나눗셈을 수행하므로, 입력값에 따라 11.75처럼 소수점 아래 값이 포함된 결과가 출력될 수 있습니다.