문제 상황
다음과 같이 배열 안에 여러 개의 하위 배열이 들어 있는 2차원 배열이 있다고 가정해 보겠습니다.
const arr = [[12, 56], [3, 45], [23, 2], [2, 6], [2, 8]];
바깥 배열의 요소 개수에는 제한이 없지만, 각 하위 배열은 반드시 숫자 두 개만 포함해야 한다는 점에 유의해야 합니다.
각 하위 배열의 두 숫자는 하나의 분수를 나타냅니다. 예를 들어 첫 번째 하위 배열은 12/56, 두 번째 하위 배열은 3/45와 같은 식입니다.
우리가 작성해야 할 JavaScript 함수는 이런 배열을 입력받아 모든 하위 배열이 나타내는 분수들의 합을 계산하는 것입니다.
단, 합을 구할 때 소수로 변환하면 안 되며 반드시 분수 형태 그대로 계산해야 합니다.
그리고 최종 결과는 결과 분수를 나타내는 두 개의 요소를 가진 배열 형태로 반환해야 합니다.
구현 예시
이 함수의 전체 코드는 다음과 같습니다.
const arr = [[12, 56], [3, 45], [23, 2], [2, 6], [2, 8]];
const gcd = (a, b) => {
let num = 2, res = 1;
while(num >= Math.min(a, b)){
if(a % num === 0 && b % num === 0){
res = num;
};
num++;
};
return res;
}
const sumFrac = (a, b) => {
const aDenom = a[1], aNumer = a[0];
const bDenom = b[1], bNumer = b[0];
let resDenom = aDenom * bDenom;
let resNumer = (aDenom*bNumer) + (bDenom*aNumer);
const greatestDivisor = gcd(resDenom, resNumer);
return [resNumer/greatestDivisor, resDenom/greatestDivisor];
};
const sumArrayOfFractions = arr => {
return arr.reduce((acc, val) => sumFrac(acc, val));
};
console.log(sumArrayOfFractions(arr));코드 동작 원리
gcd 함수: 두 수의 최대공약수(GCD)를 구합니다. 계산된 분수를 기약분수로 약분하기 위해 반드시 필요한 과정입니다.
sumFrac 함수: 두 분수를 더합니다. 분모끼리 곱해 공통 분모를 만들고, 분자는 교차 곱셈으로 계산한 뒤 최대공약수로 약분하여 가장 단순한 형태의 분수를 반환합니다.
sumArrayOfFractions 함수: reduce 메서드를 활용해 배열의 첫 번째 분수부터 마지막 분수까지 순차적으로 누적하여 더함으로써 최종 합분수를 구합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[ 1731, 140 ]
즉, 주어진 다섯 개의 분수 12/56, 3/45, 23/2, 2/6, 2/8을 모두 더하면 1731/140이 되며, 이 값은 이미 약분된 기약분수 형태입니다.