문제 이해하기
이번 글에서는 숫자 하나를 인자로 받아, 그 숫자를 구성하는 각 자릿수 중에서 원래 숫자를 나머지 없이 완전히 나눌 수 있는 자릿수의 개수를 세어 반환하는 JavaScript 함수를 작성해 보겠습니다.
예를 들어 입력 숫자가 다음과 같다고 가정해 봅시다.
const num = 148;
그렇다면 기대하는 출력 결과는 다음과 같습니다.
const output = 2;
그 이유는 148은 자릿수 1과 4로는 나누어떨어지지만(148 ÷ 4 = 37), 마지막 자릿수인 8로는 나누어떨어지지 않기 때문입니다(148 ÷ 8 = 18.5). 따라서 조건을 만족하는 자릿수는 총 2개입니다.
해결 접근 방식
이 문제는 다음과 같은 단계로 해결할 수 있습니다.
- 숫자를 문자열로 변환하여 각 자릿수에 손쉽게 접근합니다.
- 각 자릿수를 다시 숫자로 변환한 뒤, 원래 숫자를 해당 자릿수로 나눴을 때 나머지가 0인지 확인합니다.
- 나누어떨어지는 경우 카운트를 1씩 증가시킵니다.
- 모든 자릿수를 검사한 후 최종 카운트를 반환합니다.
구현 예제
위 접근 방식을 코드로 구현하면 다음과 같습니다.
const num = 148;
const countDividingDigits = (num = 1) => {
let count = 0;
const numStr = String(num);
for(let i = 0; i < numStr.length; i++){
const curr = +numStr[i];
if(num % curr === 0){
count++;
}
}
return count;
};
console.log(countDividingDigits(num));출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
2
코드 상세 설명
String(num): 숫자를 문자열로 변환하여 인덱스로 각 자릿수에 접근할 수 있게 합니다.+numStr[i]: 단항 더하기 연산자(+)를 사용해 문자 형태의 자릿수를 숫자로 변환합니다.num % curr === 0: 나머지 연산자(%)를 활용해 해당 자릿수로 숫자가 정확히 나누어떨어지는지 판별합니다.
개선된 버전: 0 처리하기
실무 관점에서 한 가지 주의할 점이 있습니다. 숫자에 0이 포함된 경우, 어떤 수도 0으로 나눌 수 없기 때문에 num % 0은 NaN이 되어 의도하지 않은 동작이 발생할 수 있습니다. 따라서 0인 자릿수를 미리 건너뛰는 안전 장치를 추가하는 것이 좋습니다.
const countDividingDigitsSafe = (num = 1) => {
let count = 0;
const numStr = String(Math.abs(num));
for(const ch of numStr){
const digit = +ch;
if(digit !== 0 && num % digit === 0){
count++;
}
}
return count;
};
console.log(countDividingDigitsSafe(105)); // 출력: 2 (1과 5로 나누어떨어짐)이 버전은 Math.abs()를 사용해 음수 입력도 올바르게 처리하며, 0인 자릿수는 나눗셈 검사 전에 제외하므로 더 견고하게 동작합니다.