27. 콜라츠 추측 (JavaScript)
문제 설명
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을 완성해 주세요. 단, 작업을 500번을 반복해도 1이 되지 않는다면 –1을 반환해 주세요.
제한 사항
- 입력된 수, num은 1 이상 8000000 미만인 정수입니다.
입출력 예시
입출력 설명
입출력 예 #1
문제의 설명과 같습니다.
입출력 예 #2
16 -> 8 -> 4 -> 2 -> 1 이되어 총 4번만에 1이 됩니다.
입출력 예 #3
626331은 500번을 시도해도 1이 되지 못하므로 -1을 리턴해야합니다.
나의 풀이
function solution(num) {
if (num==1){return 0}
var count = 0;
do{
if (num %2 ==0){
num=num/2;
count +=1;
if (count >500) {return -1}
}
else{
num=(num*3)+1;
count +=1;
if (count >500) {return -1}
}
}while(num>1);
return count
}
의식의 흐름대로 코딩하고 제출했더니 13번 케이스에서 막혔다.(실패)
그래서 2번째 줄에 num이 1일 때를 추가했다.
저 라인이 없으면 num이 1일 때 num은 do while 구문으로 들어가 반복문을 돌게 된다....
모범 답안 1)
function collatz(num,count = 0) {
return num == 1 ? (count >= 500 ? -1 : count) : collatz(num % 2 == 0 ? num / 2 : num * 3 + 1,++count);
}
다음과 같은 순서도를 가진다.
function collatz가 collatz안에도 존재하며 num과 count를 변화시켜 num이 1이 되어야만 리턴한다.
재귀함수.
count가 500이상이 되더라도 num이 1이 될 때까지 함수가 실행되기 때문에,
다음의 모범답안2) 보다 성능이 떨어진다.
모범 답안 2)
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;
}
while문을 통해 num은 1이 아니고, answer(위에서의 count개념)가 500이 아닐 동안
콜라츠 추측 알고리즘을 실행하고 answer에 +1을 하여 반복한다.
while문을 벗어나서 num이 1이되면 answer를, 1이 아니면(count가 500이어서 나온 경우) -1을 반환한다.
for 문 / while 문 의 차이
일반적으로 반복 횟수가 예측 될 때는 for 문으로 반복,
반복 횟수를 예측할 수 없을 때 while 문으로 반복한다.
for 문은 초기값이 주어진 조건을 만족시키는 동안만 실행된다.
ex 1) for( i=0; i<5; i++){ }
ex 2) while (i < 5){ }