20240104 (목) 코딩일지

2024. 1. 4. 21:00TIL

오늘은 TodoApp 스텝4를 진행할까 했지만 도저히 감이 안잡히길래 과감하게 포기하고 다른 공부를 진행했다.

(아직 내수준으로는 이른것 같다.)

 

어제 했던 TodoApp을 천천히 둘러보면서 되새기고, 아주 살짝 수정해줬다.

남은시간엔 그동안 많이 못했던 코드카타위주로 해봤는데

시간을 정하고 하기보다는 일단 한문제한문제 자세하게 훑으면서 하는게 나한테는 더 맞는 것 같아서 시간제한을 두진 않았다. 사실 시간제한내에 풀수있는 문제가 많이 없기도 하다.

시간제한을 두고 푸는 건 나중에 따로 해보든지 하고 우선 오늘 푼것중 직접 풀수있던것중 기억에 남는것을 하나 가져왔다.

 

코드카타 23. 콜라츠 추측

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 미만인 정수입니다.
입출력 예nresult
6 8
16 4
626331 -1
입출력 예 설명

입출력 예 #1
문제의 설명과 같습니다.

입출력 예 #2
16 → 8 → 4 → 2 → 1 이 되어 총 4번 만에 1이 됩니다.

입출력 예 #3
626331은 500번을 시도해도 1이 되지 못하므로 -1을 리턴해야 합니다.

(음.. 그대로 복사했더니 가시성이 조금 떨어지는듯 하다..)

 

일단 입력되는 수를 num이라 정하고 반환할 값(반복횟수)를 answer이라고 정했다.

 

일단 조건이 세가지였다.

1. 입력된 숫자( num )가 1인경우에는 0을 리턴

2. 위 조건대로 반복하는데 만약 반복횟수( answer )가 500번 이상이라면 -1을 리턴

3. 위 조건에 위배되지않는 범위내에서 반복횟수 ( answer ) 를 리턴

 

우선 반복 이라는 단어를 보자마자 이건 for 아니면 while 문을 써야겠구나 싶었고,

그 중에서도 이 경우는 반복횟수가 정해져 있지 않기때문에 for보단 while을 써야겠다고 생각했다.

 

일단 조건 1. 입력된 숫자( num )가 1인경우에는 0을 리턴

if (num == 1) answer = 0

일단 이경우는 쉽다. 

 

조건 2. 위 조건대로 반복하는데 만약 반복횟수( answer )가 500번 이상이라면 -1을 리턴

이경우엔 반복횟수를 따로 세어줘야하는데 반복문 안에 answer++를 추가해주고 계속 반복하다가

if (answer == 500) answer = -1

이런식으로 구현했다.

 

조건 3. 위 조건에 위배되지않는 범위내에서 반복횟수 ( answer ) 를 리턴

이경우에도 반복횟수를 세어줘야한다.

answer++

또 여기서는 위의 조건에 따라 반복을 해줘야하는데,

1-1. 입력된 수가 짝수라면 2로 나눕니다. 
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다. 
2. 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다. 

 

 while (true) {  //여기서 반복문 while을 써준다.
            if (num == 1) {  //2. 만약 num이 1이되면 반복을 멈춘다.
               break
            } else {
                answer++  //여기서 반복횟수를 세어준다.
                if (num % 2 == 0) {  //1-1 num이 짝수라면 2로 나눈다.
                    num /= 2
                } else {
                    var temp  = num.toDouble() //1-2 그외(홀수일때)에는 3을곱하고 1을 더한다.
                    temp = temp * 3 + 1
                    num = temp.toInt()
                }
            }
        }

 

근데 실행하려는 도중 num쪽에 오류가 하나 생겼다.

오류 설명을 읽고서 해결해보려 했지만 이해가 가진 않았다.

혹시나 하는 마음에 var a = num 이라는 값을 하나 추가해서 진행 해봤는데 이 경우에는 해결되었다.

 

그래서 완성된 코드

fun solution(num: Int): Int {
    var answer = 0  //일단 기본값으로 answer을 0으로 잡아놨다.
    var value = num //오류가 생겨 추가한 변수
    while (true) {
        if (value == 1) {
           break
        } else if (answer == 500) {
            answer = -1
            break
        } else {
            answer++
            if (value % 2 == 0) {
                value /= 2
            } else {
                var temp  = value.toDouble()
                temp = temp * 3 + 1
                value = temp.toInt()
            }
        }
    }
    return answer
}

 

내가 예상하기론 솔루션메소드를 불러올때 코드가

fun main() {
    val a = Solution()
    a.solution(num)
}

 

이런식이지 않을까 싶은데

num이 var값이 아닌 val 값이라서 그런건가 싶었다.

 

오늘의 한마디 : 요새 조금 느슨해진것 같다. 다시 맘을 다잡아야겠다.