1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될 때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다.
1-1. 입력된 수가 짝수라면 2로 나눕니다. 1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다. 2. 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다.
예를 들어, 주어진 수가 6이라면 6 → 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 이 되어 총 8번 만에 1이 됩니다. 위 작업을 몇 번이나 반복해야 하는지 반환하는 함수, solution을 완성해 주세요. 단, 주어진 수가 1인 경우에는 0을, 작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.
num은 1 이상 8,000,000 미만인 정수입니다.| n | result |
|---|---|
| 6 | 8 |
| 16 | 4 |
| 626331 | -1 |
입출력 예 #1
문제의 설명과 같습니다.
입출력 예 #2
16 → 8 → 4 → 2 → 1 이 되어 총 4번 만에 1이 됩니다.
입출력 예 #3
626331은 500번을 시도해도 1이 되지 못하므로 -1을 리턴해야 합니다.
문제 자체가 어려운 건 아니었는데 수정하느라 더 오래 걸린 것 같다.
문제에서 원하는 것은 반복 횟수였는데, 처음 문제에 접근할 때는 입력 받은 수를 1로 만드는 데만 집중해서 테스트 케이스 실행 결과를 돌려본 다음에 잘못된 점을 알았다. 제발 문제 천천히 읽어보고 풀기…!
function solution(num) {
let number = num;
let answer = 0;
while (number !== 1) {
number = number % 2 === 0 ? number / 2 : number * 3 + 1;
answer++;
if (answer >= 500) {
return -1;
}
}
return answer;
}
이건 좋아요 수가 가장 많았던 풀이
조건 범위 자체를 조건식에 넣어서 간결하게 풀고, return문에도 삼항연산자를 사용해서 마무리 한 풀이다. 진짜 깔끔하다…!
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;
}
재귀를 이용한 풀이
function collatz(num, count = 0) {
return (num == 1) ? ((count >= 500) ? -1 : count) : collatz((num % 2 == 0) ? num / 2 : (num * 3) + 1, ++count);
}
퍼포먼스가 안 나온다는 지적에 대한 댓글이 있었는데
재귀함수 대단하네요, 그런데 재귀함수라서 퍼포먼스가 안 나오는 게 아니라 num이 1인 지만 체크해서 (count가 500을 넘든말든 상관 안함, 어차피 결국 1은 되니까) 그런 거네요. 이렇게 1을 먼저 체크하고, count까지 체크하면 오히려 while문보다 조금 더 빠르네요. return num == 1 ? count : count >= 500 ? -1 : solution(num % 2 == 0 ? num / 2 : num * 3 + 1,++count);
카운트 횟수에 대한 체크까지 하는 방식으로 수정하면 훨씬 빠르다고 한다.