이번 글에서는 세 개의 숫자를 인자로 받는 JavaScript 함수를 작성해 보겠습니다. 편의상 이 세 숫자를 각각 a, b, n이라고 부르겠습니다.
함수가 해야 할 일은 다음과 같습니다.
- 모든 n자리 숫자를 대상으로 검사를 수행합니다.
- 짝수 위치(오른쪽 끝 자리를 0번째로 했을 때 0, 2, 4...번째)의 자릿수 합이 a로 나누어 떨어져야 합니다.
- 홀수 위치의 자릿수 합이 b로 나누어 떨어져야 합니다.
- 조건을 만족하는 모든 숫자를 배열에 담아 반환하며, 조건에 맞는 숫자가 하나도 없으면 빈 배열을 반환합니다.
구현 코드
const indexSum = (num, sumOdd = 0, sumEven = 0, index = 0) => {
if(num){
if(index % 2 === 0){
sumEven += num % 10;
}else{
sumOdd += num % 10;
};
return indexSum(Math.floor(num / 10), sumOdd, sumEven, ++index);
};
return {sumOdd, sumEven};
};
const divides = (b, a) => a % b === 0;
const countNum = (n, first, second) => {
let start = Math.pow(10, (n-1));
const end = Math.pow(10, n)-1;
const res = [];
while(start <= end){
const { sumEven, sumOdd } = indexSum(start);
const condition = divides(first, sumEven) && divides(second,sumOdd);
if(condition){
res.push(start);
};
start++;
};
return res;
};
console.log(countNum(3, 5, 3));
코드 동작 원리
indexSum 함수는 재귀 호출을 통해 숫자를 한 자리씩 분해합니다. 오른쪽 끝 자리부터 위치 인덱스(index)를 0으로 시작해, 인덱스가 짝수인 자리의 숫자는 sumEven에, 홀수인 자리의 숫자는 sumOdd에 더합니다. 모든 자릿수를 처리하면 두 합을 객체 형태로 반환합니다.
divides 함수는 나머지 연산자(%)를 활용해 어떤 수가 다른 수로 나누어 떨어지는지 판별하는 간단한 헬퍼 함수입니다.
countNum 함수는 n자리 숫자의 전체 범위(10n-1부터 10n-1까지)를 순회하면서 각 숫자마다 앞서 설명한 두 조건을 검사하고, 조건을 만족하는 숫자만 결과 배열에 추가한 뒤 최종적으로 반환합니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
[ 104, 109, 134, 139, 164, 169, 194, 199, 203, 208, 233, 238, 263, 268, 293, 298, 302, 307, 332, 337, 362, 367, 392, 397, 401, 406, 431, 436, 461, 466, 491, 496, 500, 505, 530, 535, 560, 565, 590, 595, 604, 609, 634, 639, 664, 669, 694, 699, 703, 708, 733, 738, 763, 768, 793, 798, 802, 807, 832, 837, 862, 867, 892, 897, 901, 906, 931, 936, 961, 966, 991, 996 ]
예를 들어 104를 살펴보면, 오른쪽부터 짝수 위치의 자릿수는 4와 1로 그 합이 5(a = 5로 나누어 떨어짐), 홀수 위치의 자릿수는 0으로 그 합이 0(b = 3으로 나누어 떨어짐)이므로 두 조건을 모두 만족해 결과에 포함됩니다.