CODING/스파르타 내일배움캠프 TIL

21_콜라츠 추측_계산기 과제 해설_25.1.10(금)

codingTrip 2025. 1. 10. 22:09

코트카타

23) 콜라츠 추측

나의 풀이

class Solution {
    public int solution(int num) {
        int answer = 0;
        long longNum = num;

        if (longNum == 1) {
            answer = 0;
        } else {
            while (answer < 500) {
                if (longNum % 2 == 0) {
                    longNum = longNum / 2;
                    answer++;
                } else {
                    longNum = longNum * 3 + 1;
                    answer++;
                }
                if (longNum == 1) {
                    break;
                }
            }
            if (answer >= 500) {
                answer = -1;
            }
        }
        return answer;
    }
}

내가 생각한 코드의 흐름은 어느 정도 맞다고 생각했는데

아래 표처럼 테스트 결과 626331 숫자가 500번을 넘어가지 않고 488번에 그치는 일이 발생했다.

n result 나의 테스트 결과
6 8 O
16 4 O
626331 -1 X

 

몇 번째에서 오버플로우가 발생했는지 파악

이에 대한 원인은 int 타입에 있었다.

int의 값 범위는 -2,147,483,648 ~ 2,147,483,647 인데

계속 반복해서 진행하다보면 오버플로우가 발생하여 범위 선에서만 값을 도출해내기 때문이었다.

위 사진을 보면 해당 계산은 음수가 나올 수 없는 계산인데, 104번부터 107번까지 음수 값이 나오고 있다.

따라서 나는 Long 타입의 변수를 새로 생성해서 num에 값을 넣어주고 계산을 했다.

 

선생님께서 자바 초반에 왜 그렇게 값의 범위에 대해 강조하셨는지 깨닫게 되는 시간이었다.


<계산기 과제 해설>

표준예외

if (secondNumber == 0) {
      throw new IllegalArgumentException("나눗셈 연산에서 분모(두 번째 정수)가 0일 수 없습니다.");
}

이렇게 예외처리를 할 수 있다는 점이 신기했다.

 

equals 사용시

"exit".equals(next)
next.equals("exit")

이 중에서 위의 것을 사용하는 것을 습관 들이라고 말씀해주셨다.

왜냐하면 "exit"이 값은 절대로 Null이 될 수 없기 때문에

그 무시무시한 NullPointerException이 발생하는 것을 예방해주기 때문이다.

이것을 Null safe라고 하셨다.

확실하게 Null이 아닌 값이 앞에 오는 것을 습관 들이라고 하셨다.

 

List

private final List<Double> resultList = new ArrayList<>();

final로 설정한 이유는 이 리스트는 참조형이라서 주소값은 그대로 이기 때문에

다른 개발자들에게 절대로 재정의 하지 말라는 메시지를 주고 싶다면 final을 붙이라고 하셨다.

나는 Int타입으로 만들었는데, 나누기를 하면 소수점이 생길 것이라고 생각하지는 못했다.

 

그리고 노란색 줄로 경고가 뜨면 무시하지 말고 꼭 확인해보라고도 하셨다.

 

toString 재정의

calculator.getResultList();
public List<Double> getResultList() {
        return resultList;
    }

이와 같은 메소드가 동작할 때, 주소값이 아닌 값이 나오는 이유는

List는 toString이 내부적으로 구현된 것이라고 하셨다.

 

레벨 3부터는 쉬운 버전과 어려운 버전이 있는데

이는 눈으로 한 번 쓱 훑어보면서 참고만 해야할 것 같다.

 

참고:https://github.com/f-api/calculator