[프로그래머스 | Javascript] 코딩테스트 입문 - 분수의 덧셈

박기영·2022년 10월 22일
1

프로그래머스

목록 보기
57/159
post-custom-banner

solution

function solution(denum1, num1, denum2, num2) {
    let a = num1;
    let b = num2;
    
    // 유클리드 호제법. 최대공약수 구하기
    while(a % b !== 0){
        let r = a % b;
        
        if(r !== 0){
            a = b;
            b = r;
        }
    }
    
    // 최소공배수 = 두 자연수의 곱 / 최대공약수
    // 공통 분모가 될 수
    let min = (num1 * num2) / b;
    
    // 분모의 변경에 따른 분자 계산
    let quotient1 = min / num1;
    let quotient2 = min / num2;

    let newdenum1 = quotient1 * denum1;
    let newdenum2 = quotient2 * denum2;
    
    let newdenum = newdenum1 + newdenum2;
    
    // 기약 분수로 만들어주기
    // min과 newdenum의 최대공약수를 찾고, 각각을 최대공약수로 나눠주면 됨
    a = min;
    b = newdenum;
    
    // 유클리드 호제법. 최대공약수 구하기
    while(a % b !== 0){
        let r = a % b;
        
        if(r !== 0){
            a = b;
            b = r;
        }
    }

    let numerator = newdenum / b;
    let denominator = min / b;
    
    let ans = [];
    
    ans.push(numerator);
    ans.push(denominator);
    
    return ans;
}

의식의 흐름대로 작성한 코드이다.
방법은 이렇다.

  1. 두 분수의 합을 구하기 위해서는 분모를 같은 숫자로 만들어야한다.
  • 두 분모의 최소공배수를 구해서 그 값을 새로운 분모로 만들어준다.
  1. 두 분자의 합을 구하기 위해서는 분모가 얼만큼 변경됐는지 알아야한다.
  • 각각 분모가 최소공배수가 되기 위하여 몇이 곱해졌는지 판단한 뒤, 그 숫자를 각각의 분자에 곱해준다.
  • 그렇게 구한 두 분자는 분모가 같은 상황이므로, 그대로 더해준다.
  1. 기약 분수를 만들어야한다.
  • 모든 덧셈이 마무리된 분자와 분모의 최대공약수를 구한 뒤, 그 숫자로 분자와 분모를 나눈다.

위 방법을 통해 구현했는데, 사실 이렇게까지 해야하는 문제인건가 싶기도하고...
다른 방법이 있지않을까싶다.

일단, 위 코드는 최대공약수, 최소공배수를 구하는 방법이 반복되므로 따로 빼줘서 사용하고싶다.

코드를 아래와 같이 수정했다.

// 유클리드 호제법. 최대공약수, 최소공배수 구하기
function euclid(num1, num2){
    let a = num1;
    let b = num2;

    // 최대공약수 구하기
    while(a % b !== 0){
        let r = a % b;
        
        if(r !== 0){
            a = b;
            b = r;
        }
    }
    
    // 최소공배수 = 두 자연수의 곱 / 최대공약수
    let min = (num1 * num2) / b;
    
    // 최대공약수, 최소공배수를 배열 형태로 return
    return [b, min];
}

function solution(denum1, num1, denum2, num2) {
    // num1과 num2에 대한 최대공약수, 최소공배수 구하기
    const [max, min] = euclid(num1, num2);
    
    // 분모의 변경에 따른 분자 계산
    let quotient1 = min / num1;
    let quotient2 = min / num2;

    let newdenum1 = quotient1 * denum1;
    let newdenum2 = quotient2 * denum2;
    
    let newdenum = newdenum1 + newdenum2;
    
    // 기약 분수로 만들어주기
    // min과 newdenum의 최대공약수를 찾고, 각각을 최대공약수로 나눠주면 됨
    const [newMax, newMin] = euclid(min, newdenum);

    let numerator = newdenum / newMax;
    let denominator = min / newMax;
    
    let ans = [];
    
    ans.push(numerator);
    ans.push(denominator);
    
    return ans;
}

코드는 보기 좋아진 것 같은데....
걸리는 시간은 위쪽(정리 전) 코드가 더 빠르다.
케이스별로 많게는 2배까지 차이가 난다.

profile
나를 믿는 사람들을, 실망시키지 않도록
post-custom-banner

0개의 댓글