:ledger: 문제 설명

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

:one: 제한사항

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

:two: 입출력 예

n m return
3 12 [3,12]
2 5 [1,10]

:three: 입출력 예 설명

:pushpin: 3-1) 입출력 예 #1

  • 위의 설명과 같습니다.

:pushpin: 3-2) 입출력 예 #2

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

:ledger: 문제 풀이

const solution = (n, m) => {
  let num1 = [];
  let num2 = [];

  for (let i = 1; i <= n; i++) {
    if (n % i === 0) num1.push(i);
  }

  for (let j = 1; j <= m; j++) {
    if (m % j === 0) num2.push(j);
  }

  let divisor = num1.filter((list) => num2.includes(list));
  let result1 = Math.max(...divisor);

  let result2 = (n * m) / result1;

  return [result1, result2];
};

solution(2, 5);

:computer: 풀이

  1. 먼저 최대 공약수와 최소 공배수의 값을 구하기 위해 num1, num2 변수를 초기화해줬다.
  2. 약수를 구하기 위해 n,m 을 for문으로 선언한 변수에 추가해줬다.
  3. 공약수를 구하기위해 divisor 변수에 num1에 있는 값 중 num2에도 존재하는 값만 필터링해줬다.
  4. 공약수 중 가장 큰 값(최대 공약수)를 찾아서 result1 에 할당했다.
  5. 두 수의 곱(divisor)을 최대공약수로 나누어 최소 공배수를 계산해서 result2에 할당했다.

:fire: 다른 사람의 풀이 참고

친절하게 설명해주는 사람이 있어서 아래와 같이 풀었는데, 신기했다.

  1. for 첫번째 인자는 루프에 들어가기 전 지정하는 값으로 a와 b가 변하기 전에 미리 최소공배수 구할 때 쓸 a * b를 선언해둠.
  2. 두 번째 인자는 루프 내에서 계속 초기화되며 true를 반환하는 동안 반복함. m % n이 0이 나오는 순간 false를 반환하여 세 번째 인자를 연산하지 않고 탈출.
  3. 세 번째 인자는 루프 내에서 반복해서 a, b를 바꿔서 유클리드 호제법을 연산해줌.
  4. ab를 미리 선언해두었기에 최소공배수를 구할 때 사용가능. 다만 지역변수를 쓸 수 있는 var의 특징이고 let, const로 선언해서 쓰려면 for문 이전에 미리 할당해줘야 함.
function gcdlcm(a, b) {
  var r;
  for (var ab = a * b; (r = a % b); a = b, b = r) {}
  return [b, ab / b];
}

출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges