문제 설명
첫 번째 분수의 분자와 분모를 뜻하는 numer1, denom1, 두 번째 분수의 분자와 분모를 뜻하는 numer2, denom2가 매개변수로 주어집니다. 두 분수를 더한 값을 기약 분수로 나타냈을 때 분자와 분모를 순서대로 담은 배열을 return 하도록 solution 함수를 완성해보세요.
제한사항
0 <numer1, denom1, numer2, denom2 < 1,000
입출력 예
numer1 denom1 numer2 denom2 result
1 2 3 4 [5, 4]
9 2 1 3 [29, 6]
입출력 예 #1
1 / 2 + 3 / 4 = 5 / 4입니다. 따라서 [5, 4]를 return 합니다.
입출력 예 #2
9 / 2 + 1 / 3 = 29 / 6입니다. 따라서 [29, 6]을 return 합니다.
말 그대로 분모가 다른 수의 배수가 아니면 서로 곱한게 최소공배수일테니
아래처럼 작성했으나 입출력 예시는 통과했지만 채점에서 통과하지 않았다.
뭘 놓친거같은데 ㅇㅅㅇ...
function solution(n1, d1, n2, d2) {
let answer = [(n1*d2) + (n2*d1),(d1*d2)]
if(d1%d2 === 0){
answer = [answer[0]/d1*d2, answer[1]/d1*d2]
} else if(d2%d1 === 0){
answer = [answer[0]/d2*d1, answer[1]/d2*d1]
}
return answer;
}
반례를 구해서 돌려보니 오류 원인을 알게되었다.
분자와 분모의 공약수로 나눠주는걸 안함
반례
(4, 8, 8, 16) 1,1
최대공약수는 무엇인가 = 공통 약수중에 가장 큰 수
검색해보니 유클리드 호제법에 의하면 다음과 같이 구할 수 있고
const gcd = (a, b) => a % b === 0 ? b : gcd(b, a % b);
재귀 짱이다....
분자와 분모를 각각 그 둘의 최대공약수로 나누어주면 되는 간단한 문제였다.
기존 코드에
최대공약수 구하는 코드 추가하고
d2*d1
로 나눠주던걸 최대공약수로 나눴다.
function solution(n1, d1, n2, d2) {
const gcd = (a, b) => a % b === 0 ? b : gcd(b, a % b);
let answer = [(n1*d2)+(n2*d1),(d1*d2)]
return [answer[0]/gcd(answer[0], answer[1]), answer[1]/gcd(answer[0], answer[1])]
}
반례 성공하고 제출 성공!