[JavaScript] 최대공약수와 최소공배수 (GCD & LCM)

프로그래머스 (feat. 유클리드 호제법)

문제 설명

두 수를 입력받아 두 수의 최대공약수와 최소공배수를 반환하는 함수, solution을 완성해 보세요. 배열의 맨 앞에 최대공약수, 그다음 최소공배수를 넣어 반환하면 됩니다. 예를 들어 두 수 3, 12의 최대공약수는 3, 최소공배수는 12이므로 solution(3, 12)는 [3, 12]를 반환해야 합니다.

제한 사항

두 수는 1이상 1000000이하의 자연수입니다.

입출력 예

nmreturn
312[3, 12]
25[1, 10]

입출력 예 설명

  • 입출력 예 #1
    • 위의 설명과 같습니다.

입출력 예 #2

  • 자연수 2와 5의 최대공약수는 1, 최소공배수는 10이므로 [1, 10]을 리턴해야 합니다.

💬 생각하고 생각하고 생각했지만.. 해결 방법이 떠오르지 않았다. 결국 googling을 했고 유클리드 호제법 (Euclidean algorithm)의 존재를 알게되었다. 이 방법을 알면 쉽게 문제를 풀 수 있다고 한다. 글을 보고 이해하려고 했지만 쉽지 않았다. 여기저기 검색해보다가 한 유튜브 영상을 찾았는데 정말 쉽게 잘 알려준다. 아래의 영상을 보고 바로 이해 ! (초등 수학이라는게 충격 🙀 ㅋㅋ)

💡 유클리드 호제법이란 ?

구하기 어려운 최대공약수를 쉽게 구할 수 있게 하는 방법이다. 예를 들어 100과 200의 최대공약수를 구하는 방법은

(우선, 큰 수로 작은 수를 나눠줌)

199 ÷ 100 = 1 ... 99

100 ÷ 99 = 1 ... 1

99 ÷ 1 = 99 ... 0

나머지가 0 이 나왔을 때, 나눠준 수, 즉 1 이 최대공약수가 된다.


자, 이제 유클리드 호제법도 알았고 문제를 풀어볼까?! 했는데!!! 유클리드호제법을 알면 문제가 쉽게 풀린다고 들었는데!!! 문제가 풀리지 않는다. 뭐가 문제인가?! 부트캠프 동기님이 와서 알려주셨는데 풀고나니 유클리드 호제법을 이해하지 못해도 푸는게 가능했다 🫠

나의 풀이

function solution(n, m) {
    const arr = [n,m];
    const maxNum = Math.max(...arr)
    const GCDarr = [];
    for(let i=1; i<maxNum+1; i++) {
        if(n%i ===0 && m%i ===0) {
            GCDarr.push(i)
        }
    }
    const GCD = GCDarr.pop();
    const LCM = n*m / GCD
    return [GCD, LCM]
}

문제를 푼 방법 :

  1. array에 두 자연수 n과 m을 넣어준 뒤, Math.max()를 이용하여 n과 m중 큰 수를 구한다.
  2. i의 1번째부터 1번에서 구한 Max까지의 수를 n 과 m으로 나눠서 나머지가 0인 수를 구해 배열에 넣어준다. (약수 구하기)
  3. 배열에 들어간 수 중에 마지막 수가 GCD(최대공약수)이다. pop()을 이용해서 마지막 수를 빼준다. 그럼 최대공약수를 구한것이다!
  4. 최소공배수를 구해야한다. 검색해보니 두 자연수의 곱 즉, n*m = LCD * GCD라고 한다. 그렇다면 최소공배수를 구하는 공식은 LCD = n*m / GCD 가 된다. 이걸로 최소공배수도 구할 수 있었다.
  5. 배열안에 GCD와 LCM을 return 주면 끝!!

최소공배수 최대공약수 초등학생 중학생때 배웠던거같은데 살면서 사용하지를 않으니 어려운문제가 되었다 ㅋㅋㅋ 그래도 이번 학습을 통해서 최소공배수와 최대공배수의 관계 및 유클리드 호제법이라는 배경지식도 알게되어 유익했다 😆