두 개의 숫자로 이루어진 배열이 주어졌다고 가정해 보겠습니다. 이 배열은 하나의 범위(range)를 지정하며, 우리는 다음 조건을 만족하는 함수를 작성해야 합니다.
즉, 주어진 두 숫자의 최소 공배수를 구하되, 그 값이 두 숫자뿐만 아니라 두 숫자 사이에 있는 모든 연속된 정수로도 나누어 떨어져야 하는 것입니다.
여기서 범위는 반드시 오름차순으로 정렬되어 있지 않을 수 있습니다. 따라서 입력 배열의 순서와 무관하게 동작해야 합니다.
문제 이해하기
예를 들어 [1, 3]이 주어진 경우를 살펴보겠습니다. 이때 구해야 하는 값은 1과 3의 최소 공배수이면서, 동시에 1과 3 사이의 모든 숫자(1, 2, 3)로도 나누어 떨어지는 가장 작은 수입니다.
- 1 → 어떤 수든 나누어 떨어짐
- 2 → 짝수여야 함
- 3 → 3의 배수여야 함
이 조건들을 모두 만족하는 가장 작은 수는 6입니다.
구현 코드
이 문제를 해결하는 JavaScript 코드는 다음과 같습니다.
const range = [1, 12];
const smallestCommon = (array = []) => {
// 배열을 복사한 뒤 오름차순으로 정렬
const arr = array.slice().sort((a, b) => a - b);
// 범위 내의 모든 숫자를 배열에 저장
const nums = [];
for (let i = arr[0]; i <= arr[1]; i++) {
nums.push(i);
}
// 범위의 최댓값에 배수를 곱해가며 조건 검사
let i = 1;
let res;
while (!nums.every(item => res % item === 0)) {
i++;
res = arr[1] * i;
}
return res;
};
console.log(smallestCommon(range));코드 동작 원리
- 정렬:
slice()로 원본 배열을 보존한 채 복사본을 만들고,sort()로 오름차순 정렬하여 입력 순서에 영향받지 않도록 합니다. - 범위 생성: 최솟값부터 최댓값까지의 모든 정수를
nums배열에 담습니다. - 후보 탐색: 범위의 최댓값(
arr[1])에 1, 2, 3... 을 차례로 곱한 값을 후보로 삼습니다. - 검증:
every()메서드로 해당 후보가 범위 내 모든 숫자로 나누어 떨어지는지 확인하고, 조건을 만족하는 첫 번째 값을 반환합니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
27720
[1, 12] 범위의 경우, 1부터 12까지의 모든 숫자로 나누어 떨어지는 가장 작은 수인 27720이 정답으로 반환됩니다.