알고리즘 CODEKATA 23 (콜라츠 추측)

오리너구리·2024년 5월 30일
0

CODEKATA

목록 보기
23/57

문제 설명

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 미만인 정수입니다.

내 풀이

최종코드

class Solution {
    fun solution(org: Int): Int {
        
        var answer = 0
        var num : Long = org.toLong()
        var repeat = 0
        
        while(num != 1L){
            
            if(num % 2 == 0L){
                num /= 2
            }else{
                num = num * 3 + 1

        }
            repeat++
            
            if(repeat>500){
                break
            }
        }
       
       if(repeat>500){
           answer = -1
       }else if (org == 1){
           answer = 0
       }else {
           answer = repeat
       }
        
        return answer
    }
}

내가 푼 과정

class Solution {
    fun solution(org: Int): Int {
        var answer = 0
        var num = org
        
        while(num != 1){
            
             if(num % 2 == 0){
            num /= 2
        }
        else{
            num *= 3
            num += 1
        }
        
        }
       
        println(num)
        
        
        return answer
    }
}

일단 if else 문 + while 문으로 1이 될때까지 num 을 조지는 함수를 만들긴 함

class Solution {
    fun solution(org: Int): Int {
        var answer = 0
        var num = org
        var repeat = 0
        
        while(num != 1){
            
            if(num % 2 == 0){
                num /= 2
                repeat += 1
                 
        }
            else{
                num *= 3
                num += 1
                repeat += 1
        }
        
        }
       
        if(org==1){
           answer = 0
       }else{
            answer = repeat
        }
        
        return answer
    }
}

반복한 횟수 세는 함수가 따로있나 봤는데 없는 것 같아서

그냥 repeat 변수를 하나 파서 코드 실행될 때마다 +1 되게 했음

그리고 만약 주어진 org 수가 1이면 0을 반환하고, 아니면 repeat을 반환하는 코드를 짬.

class Solution {
    fun solution(org: Int): Int {
        
        var answer = 0
        var num = org
        var repeat = 0
        
        while(num != 1 && repeat <500){
            
            if(num % 2 == 0){
                num /= 2
            }else{
                num *= 3
                num += 1

        }
            repeat +=1        
        }
       
       answer = when {
           org == 1 -> 0
           repeat == 500 -> -1
           else -> repeat
       }
        
        return answer
    }
}

이렇게 했는데 난관에 봉착했다.

테스트 1, 2 번은 통과하는데 3번 테스트값인 626331 에서 나는 488이 출력되는데 답지에는 -1이라고나옴.

근데 대체 코드에서 이거 왜 뭐가 틀리는지 모르겠는데 우짜지?

해결했땅

class Solution {
    fun solution(org: Int): Int {
        
        var answer = 0
        var num : Long = org.toLong()
        var repeat = 0
        
        while(num != 1L){
            
            if(num % 2 == 0L){
                num /= 2
            }else{
                num = num * 3 + 1

        }
            repeat++
            
            if(repeat>500){
                break
            }
        }
       
       if(repeat>500){
           answer = -1
       }else if (org == 1){
           answer = 0
       }else {
           answer = repeat
       }
        
        return answer
    }
}

혼자 고민하다가 아무리해도 안돼서 튜터님한테 들고 갔는데 튜터님도

코드 맞는데 왜그러지? 하셨음..

그래서 튜터님이랑

repeat +=1 을 repeat ++로 바꿔보고

while 조건에 넣어놨던 repeat 조건을 break 문으로 밖으로 빼보기도 하고이것도 해보고 저것도 해보고 하다가

튜터님한테 가기전에 이 문제 전에 푸셨던 팀원 분한테 슬랙으로 질문하고 갔었는데

그 팀원분이 오버플로우 문제라고 num 을 Long형으로 바꾸면 된다고 알려주심.. 그저 빛..

튜터님도 아 그렇네~~하면서 타입 변환하고 채점 100점 맞는거까지 지켜봐주셨다!

휴~~~

Int로 다 되는척 하고 갑자기 num하나만 Long으로 써야된다니

기출변형 에바아니냐고~!


다른 사람 풀이

class Solution {
    fun solution(num: Int): Int = collatzAlgorithm(num.toLong(),0)

    tailrec fun collatzAlgorithm(n:Long, c:Int):Int =
        when{
            c > 500 -> -1
            n == 1L -> c
            else -> collatzAlgorithm(if( n%2 == 0L ) n/2 else (n*3)+1, c+1)
        }
}

뭐 .. tailrec fun 이라는 요상한 친구를 사용해서 푸셨다. 근데 나 지금 2시간 코드카타하느라

머리가 안돌아감..몰라..나중에 알아보자

여담

아오!!! 이것때문에 거의 2시간 가까이를 코드카타만 했다.

앞으로는 알 수 없게 계산이 틀리면 데이터 타입부터 확인하자.

아니 근데 슈발 내가 626331을 콜라츠 추측 으로 1으로 만들 때 애가 범위 어디까지 갈지 어케암!!!

원래 다른 사람 풀이 하나하나 읽어보고 참고할만한 풀이 공부하려고 가져오는데 오늘은 도저히 꼴이 보기가 싫다.

하기싫을때 억지로하면 질리기때문에 오늘은 여기까징~~

profile
오리너구리입니다

0개의 댓글