정렬되지 않은 세 개의 숫자를 입력받아, 최소한의 비교 연산만으로 그중 중간값(middle)을 반환하는 JavaScript 함수를 작성해야 합니다.
예를 들어 숫자가 다음과 같다면 —
34, 45, 12
함수는 아래와 같은 값을 반환해야 합니다 —
34
접근 방식
이 문제는 세 수를 일일이 비교·정렬하는 대신, 뺄셈 결과의 부호(양수/음수)를 활용하면 단 세 번의 뺄셈과 최대 두 번의 조건 검사만으로 해결할 수 있습니다.
x = a - b: x가 양수면 a가 b보다 크고, 음수면 b가 더 큽니다.y = b - c: y가 양수면 b가 c보다 크고, 음수면 c가 더 큽니다.z = a - c: z가 양수면 a가 c보다 크고, 음수면 c가 더 큽니다.
x와 y의 곱이 양수라는 것은 두 값의 부호가 같다는 의미이며, 이는 b가 a와 c 사이에 위치한다는 뜻입니다. 따라서 이때 b가 중간값입니다. 같은 원리로 x와 z의 곱이 양수면 c가 중간값이고, 어느 쪽도 해당하지 않으면 a가 중간값이 됩니다.
예제 코드
const num1 = 34;
const num2 = 45;
const num3 = 12;
const middleOfThree = (a, b, c) => {
// x는 a가 b보다 클 때 양수, b가 a보다 클 때 음수입니다.
const x = a - b;
const y = b - c;
const z = a - c;
// x와 y의 부호가 같다면(x * y > 0), b가 중간값입니다.
if (x * y > 0) {
return b;
} else if (x * z > 0) {
return c;
} else {
return a;
}
};
console.log(middleOfThree(num1, num2, num3));출력 결과
콘솔에 출력되는 결과는 다음과 같습니다 —
34
마무리
이 방법은 배열을 정렬하지 않고도 단 몇 번의 산술 연산과 조건 검사만으로 세 수의 중간값을 구할 수 있어 매우 효율적입니다. 참고로 곱셈 대신 부호만 비교하도록 로직을 바꾸거나, Math.max와 Math.min을 활용해 (a + b + c) - Math.max(a, b, c) - Math.min(a, b, c) 형태로 풀어내는 방법도 가능합니다. 상황에 맞게 선택하여 사용하면 됩니다.