:ledger: 문제 설명

  • 1937년 콜라츠란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될 때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다.
  • 입력된 수가 짝수라면 2로 나눕니다.
  • 입력된 수가 홀수라면 3을 곱하고 1을 더합니다.
  • 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다.

예를 들어, 주어진 수가 6이라면 6 → 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 이 되어 총 8번 만에 1이 됩니다. 위 작업을 몇 번이나 반복해야 하는지 반환하는 함수, solution을 완성해 주세요. 단, 주어진 수가 1인 경우에는 0을, 작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.

:one: 제한사항

  • 입력된 수, num은 1 이상 8,000,000 미만인 정수입니다.

:two: 입출력 예

n result
6 8

:three: 입출력 예 설명

:pushpin: 3-1) 입출력 예 설명 #2

16 → 8 → 4 → 2 → 1 이 되어 총 4번 만에 1이 됩니다.

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

626331은 500번을 시도해도 1이 되지 못하므로 -1을 리턴해야 합니다.

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

주어진 수가 1인 경우에는 0을, 작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.

:three: 프로그래머스에서 제공한 코드

처음 프로그래머스에서 작성된 코드는 아래와 같다.

function solution(num) {
  var answer = "";
  return answer;
}

:ledger: 문제 풀이

const solution = (num) => {
  let n = 0; // 작업 횟수 초기화

  if (num === 1) return 0; // 1이면 0반환

  while (num !== 1) {
    // 1이되면 종료
    num % 2 === 0 ? (num = num / 2) : (num = num * 3 + 1);
    n++; // 작업횟수 500 체크하기 위해 더해줌
    if (n == 500) return -1; // 작업횟수 500이면 -1 반환
  }

  return n;
};

:one: 함수 선언

  • 화살표 함수를 사용하여 num 매개변수를 받는다.

:two: 풀이

  • 작업 횟수를 책정하기 위해 변수 n을 선언한다.
  • 반복문이 시작되기 전 if문으로 num의 값이 1일 경우 0 반환
  • while문을 사용하여 num의 값이 1이 아닐 경우 500번 까지 실행 500번이 되면 return -1
  • 반복문이 실행될 때 num%2==0(짝수일때) num은 num/2를 해준다. 아닐경우 num * 3 + 1을 해준다.
  • num의 값이 숫자 1이 되어 종료될 때 작업횟수를 반환한다.

:three: 결과 반환

  • num의 값에 6을 대입할 경우 6 % 2 === 0 조건이 참이되어 6/2 를 해주면 3이 된다.
  • num은 3이 되어 3 % 2 === 0 조건이 거짓이되어 3 * 3 + 1 를 해주면 10이 된다.
  • 위와 같이 실행되어 500번 미만까지 1이 될 경우 작업 횟수의 값이 반환되며 500번이되면 -1을 반환한다.

:four: 실행

  • console.log(solution(6)) 실행하면 8 출력
  • console.log(solution(16)) 실행하면 4 출력
  • console.log(solution(626331)) 실행하면 -1 출력

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

대부분 for 반복문과 while 반복문으로 문제를 해결했으며, 재귀함수를 통해 문제를 해결한 방법이 있는데 머릿속이 참 궁금하다.
아무래도 구조가 다른게 아닐까 싶은.. 능력자는 세상에 정말 많다.
아래의 코드는 마지막으로 return 할 때 한번더 체크해주었는데, 저렇게 작성하는 것이 옳다고 생각한다.

// [1명] while 반복문을 사용한 문제 풀이
function collatz(num) {
  var answer = 0;
  while (num != 1 && answer != 500) {
    num % 2 == 0 ? (num = num / 2) : (num = num * 3 + 1);
    answer++;
  }
  return num == 1 ? answer : -1;
}

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