자릿수 근(Digit Root)이란?
자릿수 근(digit root)은 양의 정수를 구성하는 모든 자릿수의 합으로 정의됩니다. 예를 들어 13의 자릿수 근은 1 + 3 = 4가 됩니다.
이번 글에서는 정수 배열을 입력받아 자릿수 근을 기준으로 오름차순 정렬하는 JavaScript 함수를 작성해 보겠습니다. 정렬 조건은 다음과 같습니다.
- 숫자 a가 b보다 앞에 오려면 a의 자릿수 근이 b의 자릿수 근보다 작거나 같아야 합니다.
- 두 숫자의 자릿수 근이 같다면, 일반적인 크기 비교에서 더 작은 숫자가 먼저 와야 합니다.
예를 들어 4와 13은 자릿수 근이 같습니다(각각 4). 하지만 4 < 13이므로, 두 숫자가 모두 포함된 자릿수 근 정렬에서는 4가 13보다 앞에 위치해야 합니다.
문제 예시
입력 배열이 다음과 같다고 가정해 보겠습니다.
const arr = [13, 20, 7, 4];
각 숫자의 자릿수 근을 계산하면 다음과 같습니다.
- 13 → 1 + 3 = 4
- 20 → 2 + 0 = 2
- 7 → 7
- 4 → 4
자릿수 근을 기준으로 정렬하면 2, 4, 4, 7 순서가 되고, 자릿수 근이 같은 13과 4는 실제 값이 작은 4가 먼저 옵니다. 따라서 출력 결과는 다음과 같아야 합니다.
const output = [20, 4, 13, 7];
구현 코드
먼저 재귀 함수를 이용해 각 숫자의 자릿수 합을 계산한 뒤, Array.prototype.sort() 메서드에 커스텀 비교 함수를 전달하여 정렬합니다. 비교 함수에서는 자릿수 근의 차이를 우선 확인하고, 차이가 0이면(|| 연산자 활용) 실제 값의 차이로 정렬합니다.
const arr = [13, 20, 7, 4];
// 숫자의 자릿수 합을 재귀적으로 계산하는 함수
const digitSum = (num, sum = 0) => {
if (num) {
return digitSum(Math.floor(num / 10), sum + (num % 10));
}
return sum;
};
// 자릿수 근 기준 정렬 함수
const digitalSort = (arr = []) => {
const sorter = (a, b) => {
// 자릿수 근이 같으면 실제 값으로 비교
return (digitSum(a) - digitSum(b)) || (a - b);
};
arr.sort(sorter);
};
digitalSort(arr);
console.log(arr);코드 설명
- digitSum(num): num을 10으로 나눈 몫과 나머지를 활용해 마지막 자릿수를 더하고, 재귀 호출을 통해 모든 자릿수의 합을 구합니다.
- sorter(a, b): digitSum(a) - digitSum(b)가 0이 아니면 그 값(음수 또는 양수)에 따라 정렬되고, 0이면 || 연산자에 의해 a - b 결과가 사용되어 같은 자릿수 근을 가진 숫자들은 크기순으로 정렬됩니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 출력이 나타납니다.
[ 20, 4, 13, 7 ]
결과를 보면 자릿수 근이 가장 작은 20(근: 2)이 첫 번째로, 그다음 자릿수 근이 4인 4와 13이 순서대로, 마지막으로 자릿수 근이 7인 7이 배치된 것을 확인할 수 있습니다.