이 글은 문제를 정리하고 저의 풀이를 보여드리는 거예요. 실제로 문제를 보고 풀어보세요. 클릭! 클릭! 해보세요! 🖱️
1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다.
1-1. 입력된 수가 짝수라면 2로 나눕니다.
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다.
2. 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다.위 작업을 몇 번이나 반복해야하는지 반환하는 함수, solution을 완성해 주세요.
❗단, 주어진 수가 1인 경우에는 0을, 작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.
❗입력된 수, num은 1 이상 8,000,000 미만인 정수입니다.
입력된 수가 6
이라면 6 ➡️ 3 ➡️ 10 ➡️ 5 ➡️ 16 ➡️ 8 ➡️ 4 ➡️ 2 ➡️ 1 이 되어 총 8번 만에 1이 됩니다.
16
➡️ 8 ➡️ 4 ➡️ 2 ➡️ 1 이되어 총 4번만에 1이 됩니다.
626331
은 500번을 시도해도 1이 되지 못하므로 -1을 리턴해야합니다.
while
문으로 구현할 때num /= 2
한 후, answer++
num *= 3 + 1
한 후, answer++
if num == 1
이면 return answer
for
문으로 구현할 때num /= 2
한 후, answer++
num *= 3 + 1
한 후, answer++
if num == 1
이면 return answer
num
의 자료형은 long
으로! int
는 ❌num
의 자료형이 int
이냐, long
이냐에 따라 결과가 달라진다.num
의 자료형이 long
일 때의 결과만 통과한다.while
문으로 구현num
이 1이 아닐 때while(num != 1)
while
문 시작하자 마자 바로 루프 카운팅 시작collatzCount++
while
루프가 500번 반복되면 바로 -1 반환 if
문으로 구현itsNotCollazNum
변수명으로 의미부여if(collazCount == 500) return itsNotCollazNum
num /= 2
, 홀수일 때는 num *= 3 + 1
한 후, num
에 대입num = (num%2==0) ? (num/2) : (num*3+1)
public class CollatzConjecture {
public static int solution(int num) {
int answer = 0;
while (num <= 1000) {
if(num % 2 == 0) {
num /= 2;
answer++;
}
if (num == 1)
return answer;
if(num % 2 == 1) {
num = (num * 3) + 1;
answer++;
}
}
answer = -1;
return answer;
}
}
if(num == 1)
문 위치🥲 바꿔서 다시 해봤지만 다시 실패함. 결국 예상한 실패 이유가 틀렸다는 뜻!
public class CollatzConjecture {
public static int solution(int num) {
int collatzCount = 0;
int itsNotCollatzNum = -1;
while (collatzCount <= 500) {
if (num % 2 == 0) {
num /= 2;
} else {
num = (num * 3) + 1;
}
collatzCount++;
if (num == 1) return collatzCount;
}
return itsNotCollatzNum;
}
}
while()
문 조건while(num <= 1000)
➡️ while(collatzCount <= 500)
if()
문 * 3if() if() if()
➡️ if() else if()
if(num==1)
문 위치짝수연산과 홀수 연산 사이 ➡️ 짝수 연산과 홀수 연산 뒤에
answer++
문 위치짝수 연산과 홀수 연산 각각에 ➡️ 짝수 연산과 홀수 연산에 모두 지우고, 짝수 연산과 홀수 연산이 끝나고 한번만 answer++
할 수 있도록 했다.
아까보다 틀린 횟수는 확연하게 줄긴 했다..🥲
내가 처음 문제를 풀었을 때는 6월 3일!
그러나 6월 10일에
주어진 수가 1인 경우에는 0을 반환해 주세요.
라는 제한 규칙이 추가되었다.
최근에 추가된 이 제한 규칙을 충족시키지 못했기 때문에 아무리 코드를 고쳐도 계속 똑같이 테스트5랑 테스트13번만 계속 틀리는 것이었다!
num
의 자료형 num
의 자료형이 int
일 때와 long
일 때 return
값이 달라진다.
num
의 자료형이 int
면 불합격, long
면 통과된다.
class Solution {
public int solution(long num) {
int collatzCount = 0;
int itsNotCollatzNum = -1;
while (num != 1) {
collatzCount++;
if (collatzCount == 500)
return itsNotCollatzNum;
num = (num % 2 == 0) ? num / 2 : (num * 3) + 1;
}
return collatzCount;
}
}
public static int sol(long num) {
int answer = 0;
while(num != 1){
answer++;
if(answer==500)
return -1;
if(num%2==0){
num/=2;
}else{
num=num*3+1;
}
}
return answer;
}
num
의 자료형이 int
일 때와 long
일 때 return
값이 달라진다.
public int solution(long num)
➡️ num=626331
일때 return -1
➡️ 통과
public int solution(int num)
➡️ num=626331
일때 return 488
➡️ 불합격
문제의 조건은 num
이 1일 떄는 0을 반환하고, num
이 1이 될 때까지 콜라츠연산을 반복하는 것이므로 num
이 1일 때는 루프를 타지 않아야 한다. 그러므로 while
문의 조건이 collazCount <= 500
이어야 하는 것이 아니라 num != 1
인 것이 맞다.
while
문이 시작하자마자 카운팅을 시작해야지 collazCount
가 500일 때 바로 -1
을 반환시킬 수 있기 때문이다.
while
문의 조건과 if
문의 조건을 반대로 해놔서 이때까지 틀린 것이었다.
num
이 1이면 while
문이 돌아가면 안되고
collazCount
가 500이 되면 while
문이 멈춰야 되는 것이었는데
이것을 정반대로 해서
collazCount
가 500이 될 때까지 num
이 1이어도 while
문이 돌아가게 했고 그래서 num
이 1일 때 0을 반환해야 하는데, 콜라츠 연산 횟수인 collazCount
를 반환되어 버렸다.
이 문제는 콜라츠 연산의 횟수를 요구한 것이었는데
나는 -1
을 반환했으니 당연히 틀리는 것이었다.
solution
함수의 매개변수num
의 타입이 int
면 불합격, long
이면 합격인 이유⬆️ 클릭하면 그 이유에 대한 설명으로 이동됨