알고리즘 문제 중에 쉬운 듯 생각을 잘 해야 하는 콜라츠 추측 문제를 한번 풀어봤다
문제의 요약은 대충 이렇다
- 주어진 값이 짝수 일 경우 2를 나눈다
- 주어진 값이 홀수 일 경우 3을 곱한 후에 1을 더한다
- 연산 값이 1아 될 때 까지 계속 위 작업을 반복한다
- 1인 경우에는 0을 반환한다
- 500번 이상 반복할 경우에는 -1을 반환한다
문제의 해결 과제를 이런식으로 나누어서 생각했다
1. 주어진 값이 짝수와 홀수를 검사 후 연산 기능
2. 연산 값이 1이 될 때 까지 계속 위 작업을 반복하는 기능
3. 최초 입력 값이 1인 경우와 500번 이상 반복한 경우에 예외 처리
1. 연산 횟수와 연산 값을 임시로 저장하는 변수 생성
2. 주어진 값이 짝수와 홀수를 검사 후 연산 기능
짝수와 홀수 같은 경우는 %(나머지 연산자) 를 활용하였다 만약에 2를 나머지 연산을 할경우 0이 나올 경우 짝수 이외의 값이 나올 경우 홀수로 짝수 홀수를 구분하였다
fun solution(num: Int): Int {
var answer = 0
var tempNumber = num
if(tempNumber % 2 == 0L){
tempNumber /= 2
}else{
tempNumber = (tempNumber * 3) + 1
}
return answer
}
3. 위 작업을 1이 될때 까지 반복한다
위에서 연산한 결과를 1이 될 때 까지 반복을 한다 따라서 while을 사용하여 1이 아닐때만 반복하게끔 구성을 해주었다
fun solution(num: Int): Int {
var answer = 0
var tempNumber = num
while (tempNumber != 1){
if(tempNumber % 2 == 0){
tempNumber /= 2
}else{
tempNumber = (tempNumber * 3) + 1
}
//반복할 때 마다 연산 횟수 증가
answer += 1
}
return answer
}
4. 최초 입력 값이 1인 경우와 500번 이상 반복한 경우에 예외 처리를 한다
처음 입력 받았을 때 값이 1이면 바로 함수를 리턴하며 반복 횟수가 500번이 넘었을 경우 answer에 -1을 넣고 리턴한다
fun solution(num: Int): Int {
var answer = 0
var tempNumber = num
if(tempNumber == 1) {
return answer
}
while (tempNumber != 1){
if(tempNumber % 2 == 0){
tempNumber /= 2
}else{
tempNumber = (tempNumber * 3) + 1
}
answer += 1
if(answer >= 500){
answer = -1
break
}
}
return answer
}
이런 식으로 코드를 짜고 코드를 돌려봤는데...
626331이라는 값을 넣었을 경우에 500이 넘기 때문에 예상 값이 -1 이어야 하는데 488이 나오는 것 아닌가;;
그래서 해당 부분을 확인하기 위해서 위에서 연산한 다음에 연산 결과를 출력하는 코드를 작성해서 출력해봤다
그런데..
중간에 음수가 나오는 것 아닌가;; 이게 무슨 일인가 하고 찾아봤는데
코틀린의 Int형은 4바이트(32비트) 이고 -2,147,483,648 ~ 2,147,483,647 까지 표현이 가능한데 이 값을 넘어버리면 제일 마지막에 있는 부호를 구분하는 비트를 넘어가기 때문에 의도치 않게 음수로 바뀌는 것이 었다 ( + 음수로 바뀌면서 값도 바뀌는 기적...)
따라서 이 문제는 연산 값을 Long 타입으로 바꿔서 연산을 하면 정상적으로 출력이 될 것 같아서
fun solution(num: Int): Int {
var answer = 0
var tempNumber:Long = num.toLong()
if(tempNumber == 1L) {
return answer
}
while (tempNumber != 1L){
if(tempNumber % 2 == 0L){
tempNumber /= 2
}else{
tempNumber = (tempNumber * 3) + 1
}
answer += 1
if(answer >= 500){
answer = -1
break
}
}
return answer
}
전부 Long 타입으로 바꾸고 출력해보니까 정상적으로 작동하는 것이 확인되었다
- 오늘의 결론
- 커보이는 값이 보이고 이 값을 곱하기등의 큰 연산을 반복적으로 수행할 경우에는 Long 타입을 쓰는 것이 낫다
- 물론 로직 따라 다르겠지만 ㅎㅎ
'알고리즘 > 문제풀이' 카테고리의 다른 글
(알고리즘) 멀리 뛰기 풀이 (0) | 2024.07.05 |
---|---|
(알고리즘) 기사단원의 무기 풀이 (0) | 2024.05.09 |
(알고리즘) 시저 암호 풀이 (1) | 2024.05.01 |