문제 출처 : 프로그래머스 prorammers - 평균 구하기 (링크)
문제 설명
두 수를 입력받아 두 수의 최대공약수와 최소공배수를 반환하는 함수, solution을 완성해 보세요.
배열의 맨 앞에 최대공약수, 그다음 최소공배수를 넣어 반환하면 됩니다.
예를 들어 두 수 3, 12의 최대공약수는 3, 최소공배수는 12이므로 solution(3, 12)는 [3, 12]를 반환해야 합니다.
제한사항
- 두 수는 1이상 1000000이하의 자연수입니다.
일단 초등수학교육을 까마득히 잊고 지내서,
최대공약수와 최소공배수가 뭔지 기억이 안납니다...🥲
공약수가..뭐? 서로소??
이렇게 정리하니 한결 보기편해졌다.
최대공약수 : 두 수를 완벽히 나누어 떨어지게 (나머지가 0이게)할 수 있는 제일 큰 수
36 / 12 = 3
24 / 12 = 2
최소 공배수
A. 내가 푼 답
function solution(n, m) {
var answer = [];
let greatestCommoFactor = 0;
let leastCommoMultiple = 0;
if (n % m === 0 || m % n === 0) {
greatestCommoFactor = Math.min(n, m);
leastCommoMultiple = Math.max(n, m);
} else {
for (let i = 1; i < Math.max(n, m); i++) {
if (n % i === 0 && m % i === 0) {
greatestCommoFactor = i;
}
}
leastCommoMultiple = (n * m) / greatestCommoFactor;
}
answer.push(greatestCommoFactor, leastCommoMultiple);
return answer;
}
1. 두 가지 조건 걸어주기
조건 1)
// 예
n=12, m=3
위의 예와 같이 주어진 두 수가 서로에 의해 완전히 나누어질 경우,
- 둘 중 작은 수가 '최대공약수'
- 둘 중 큰 수가 '최소공배수'
조건 2)
// 예
n=36, m=24
조건 1을 만족하지 않을 경우
최대공약수 구하기
- 최대공약수는 두 수 모두를 나누어 떨어지게 할 수 있는 최대의 수이다.
즉, 어떤 수 i로 나눌 때
36 % i == 0, 24 % i == 0 을 만족해야한다. - for문과 &&연산자를 사용해서, 조건을 만족하는 수 중 제일 큰 숫자를 '최대공약수'로 지정
최소공배수 구하기
- 최대 공약수 12는 구해 졌고,
여기서 최소 공배수를 구하려면 아래와 같이 3, 2 또는 이 두 수를 곱한 6이라는 수가 필요하다.
- 가만 보면 3, 2 라는 이 두 수도 결국 주어진 수 n, m을 최대공약수로 나눈 것이다.
36 / 12 = 3
24 / 12 = 4
// greatestCommoFactor = 12
leastCommoMultiple = a * b
a = n / greatestCommoFactor;
b = m / greatestCommoFactor;
하지만 우리는 a, b를 곱한 값이 필요한 것이므로, 값을 따로 구할 필요 없이 한 번에 구할 수 있다.
leastCommoMultiple = (n * m) / greatestCommoFactor;
B. 다른 사람의 풀이
function greatestCommonDivisor(a, b) {return b ? greatestCommonDivisor(b, a % b) : Math.abs(a);}
function leastCommonMultipleOfTwo(a, b) {return (a * b) / greatestCommonDivisor(a, b);}
function gcdlcm(a, b) {
return [greatestCommonDivisor(a, b),leastCommonMultipleOfTwo(a, b)];
}
최대공약수를 구하는 알고리즘으로 유클리드호제법 이라는 것이 있다고 한다. (참고 velog @YeYelog)
유클리드 호제법 : 두 수의 최대공약수를 구하는 알고리즘
호제법 : 두 수가 서로 상대방의 수를 나누어서 결국 원하는 수를 얻는 알고리즘
MOD연산 : 두 값을 나눈 나머지를 구하는 연산
유클리드 호제법
1. 큰 수를 작은 수로 나눔
36 % 24 == 12
2. 나눴던 수를 나머지로 나눔
24 % 12 == 0
3. 반복
4. 나머지가 0이 됐을 때, 나누는 수로 사용된 12가 36과 24의 최대공약수가 됨
새로 알게된 것들
- for 문을 사용하지 않고, 삼항연산자에 조건을 걸어 재귀함수를 사용하는 스킬...😨
- Math.abs() : 주어진 숫자의 절대 값을 반환
Math.abs(12) // 12
Math.abs(0) // 0
Math.abs(-12) // 12
반응형
'D.evelop [CS] > Algorithm' 카테고리의 다른 글
[Algorithm 030] JS - 자연수 뒤집어 배열로 만들기 (Level 01) (0) | 2021.12.02 |
---|---|
[Algorithm 029] JS - 정수 내림차순으로 배치하기 (Level 01) (0) | 2021.11.22 |
[Algorithm 027] JS - 제일 작은 수 제거하기 (Level 01) (0) | 2021.11.14 |
[Algorithm 026] JS - 짝수와 홀수 (Level 01) (0) | 2021.11.13 |
[Algorithm 025] JS - 콜라츠 추측 (Level 01) (0) | 2021.11.13 |
댓글