요즘 프로그래머스 코테를 풀어보고있는데 최소공배수, 최대공약수를 활용하면 쉽게 풀릴 문제들이 많이 보여서 한번 제대로 정리하고 넘어가려한다.
분명 초등학교에서 배웠던 것 같은데 이상하게 새롭다. 최대공약수, 최소공배수가 도대체 뭘까?
: 두 자연수의 공통된 약수 중 가장 큰 수
ex. 15와 18의 최대공약수 구하기
1, 3, 5, 151, 2, 3, 6, 9, 1833 : 2부터 두 수(a, b)의 최소값 사이의 모든 숫자로 나눠보면서 최대값 구하기
const getGcd = (a, b) => {
let gcd = 1; // 최대공약수
for (let i = 2; i <= Math.min(a, b); i++) {
if (a % i === 0 && b % i === 0) {
gcd = i;
}
}
return gcd;
}
두 자연수의 공통된 배수 중 가장 작은 수
ex. 12와 18의 최소공배수 구하기
36, 48, 60 • • •36, 54, 72, 90 • • •36 • • •36 : 두 수의 곱을 두 수의 최대공약수로 나누기
↪ 최소공배수 최대공약수 = a b
↪ 최소공배수 = a * b / 최대공약수
const getLcm = (a, b) => {
let gcd = 1; // 최대공약수
let lcm = 1; // 최소공배수
for (let i = 2; i <= Math.min(a, b); i++) {
if (a % i === 0 && b % i === 0) {
gcd = i;
}
}
lcm = (a * b) / gcd;
return lcm;
}
하지만 기원전 3세기경에 고대 그리스 수학자인 유클리드(Euclid)에 의해 발견된 굉장한 알고리즘을 사용하면 누구보다 빠르게 최대공약수를 구해볼 수 있다. 고로 "유클리드 호제법"이라는 알고리즘에 대해 알아보자.
두 수의 최대공약수를 구하는 알고리즘
※ 호재법 : 두 수가 서로 상대방 수를 나누어서 결국 원하는 수를 얻는 알고리즘
두 수를 나눈 나머지를 r이라고 할 때, 두 수 중 작은 수와 r의 최대공약수가 두 수의 최대공약수와 같다는 것을 이용하여, 과정을 반복하다가 나머지가 0이 될 때 나누는 수가 두 수의 최대공약수가 된다.
자바스크립트 코드로 구현해보면 이렇다.
1) while문으로 구현
//
const gcd = (a, b) => {
while (b > 0) {
let temp = b;
b = a % b;
a = temp;
}
return a;
};
2) 재귀함수로 구현
const gcd = (a, b) => a % b ? gcd(b, a % b) : b;
const lcm = (a, b) => a * b / gcd(a, b);