연습장

57. 분수의 덧셈 본문

프로그래머스/0단계

57. 분수의 덧셈

js0616 2023. 8. 19. 15:12

Q. 첫 번째 분수의 분자와 분모를 뜻하는 numer1, denom1, 두 번째 분수의 분자와 분모를 뜻하는 numer2, denom2가 매개변수로 주어집니다. 두 분수를 더한 값을 기약 분수로 나타냈을 때 분자와 분모를 순서대로 담은 배열을 return 하도록 solution 함수를 완성해보세요.

 


예시 1번  1/2 + 3/4 = 5/4 

예시 2번  9/2 + 1/3 = 29/6

 

이 문제의 해결에는 총 2가지 과정이 필요하다.

1. 분수의 덧셈

2. 기약분수로 표기

 

1. 분수의 덧셈 

 

분수의 덧셈은 잘 알겠지만 

분모를 통일하고 분자를 더하는것인데

 

간단하게 하자면 

 

분모끼리 곱하면 분모가 통일이 되며  이후 증가된 분자값 끼리 더하면된다.

 

num1 = 분자

num2 = 분모 라고 하면 

다음과같이 표시할 수 있다.

let num1 = numer1 * denom2 + numer2*denom1
let num2 = denom1 * denom2

 

2. 기약분수로 표기

num1 / num2 의 분수 형태로 만들어진 값을  기약분수로 바꾸려면 최대 공약수로 분모와 분자를 나누어 주면 된다.

 

최대 공약수란?

두 수를 나누었을때 나누어 떨어지는 공통의 수 중에서 가장 큰 수 이다. 

 

예를들어 12와 18의 경우

2, 3 , 6 으로 각각 나누면 나머지가 없이 나누어 떨어진다. 

그 중에서 가장 큰 수인 6이 최대 공약수가 된다.

 

코드로 이걸 어떻게 해결할까 ? 

 

2-1. num1 의  약수들을 구해 배열로 만들고

2-2. 그 배열의 원소가 num2 를 나누었을때 나머지가 없다면 그 원소는 num1, num2 의 공약수가 된다.

2-3. 그리고 그 공약수 중에서 가장 큰 수가 최대 공약수가된다.

 

 

 

// 최대공약수
const divlist = function(n,m){
    let arr = [] // 2-1) n의 약수가 들어가는 배열
    let ans = 1

    // n 의 약수를 구하는 for 문
    for (let i = n ; i>=2 ; i--){
        if(n%i == 0){
            arr.push(i)
        }
    }

    // 2-2)  n 의 약수가 m 의 약수인지 확인
    for (i of arr){
        if(m%i ==0){
            // 2-3)
            ans = i
            return ans
        }
    }
    return ans
}

 

for 문의 i 값을 n 부터 감소하도록 한 이유는

 

우리가 필요한 값은 최대 공약수 한개이므로 가장 큰값부터 비교할수있도록 배열에 담았다.

 

arr 의 가장 큰 값부터 m의 약수인지 (공약수) 인지 판단하는 두번째 for 문을 이용하고

 

arr의 원소가 m의 약수라면 최대 공약수만 구하면 되므로 더이상 진행할 필요없이

그 원소값을 retrun 하도록 ans 값에 담아주었다.

 

그리고 공약수가 없다면 즉 이미 기약분수 상태라는 의미이므로 1을 return 하도록 하였다.

 


전체 정답 코드는 다음과 같다.

 

const divlist = function(n,m){
    // 최대공약수
    let arr = []
    let ans = 1
    for (let i = n ; i>=2 ; i--){
        if(n%i == 0){
            arr.push(i)
        }
    }
    for (i of arr){
        if(m%i ==0){
            ans = i
            return ans
        }
    }
    return ans
}


function solution(numer1, denom1, numer2, denom2) {
    var answer = [];
    
    let num1 = numer1 * denom2 + numer2*denom1
    let num2 = denom1 * denom2
    
    let divnum = divlist(num1,num2)

    answer.push(num1/divnum,num2/divnum)
    
    return answer;
}

 


다른사람 풀이

function fnGCD(a, b){
    return (a%b)? fnGCD(b, a%b) : b;
}

function solution(denum1, num1, denum2, num2) {
    let denum = denum1*num2 + denum2*num1;
    let num = num1 * num2;
    let gcd = fnGCD(denum, num); //최대공약수

    return [denum/gcd, num/gcd];
}

 

나의 풀이와 비슷하나 최대 공약수를 구하는 함수가 다르다. 

 

추가 설명

'프로그래머스 > 0단계' 카테고리의 다른 글

59. 이차원 배열 대각선 순회하기  (0) 2023.08.20
58. 최빈값 구하기  (0) 2023.08.19
56. 간단한 식 계산하기  (0) 2023.07.11
55. 대문자로 바꾸기  (0) 2023.07.11
54. 조건에 맞게 수열 변환하기 2  (0) 2023.07.10