[프로그래머스_ Java_Lv1] 콜라츠 추측

박경희·2025년 2월 24일

코딩테스트

목록 보기
59/69

초반 코드(오답)

public static int solution(int num) {
        int answer = 0;
        int a = num;

        while (a != 1) {
            if (a % 2 == 0) {
                a /= 2;
                answer++;
                if (a == 1) {
                    break;
                }
            }
            if (a % 2 != 0) {
                a = (a * 3 + 1);
                answer++;
            }
            if (answer >= 500) {
                answer = -1;
                break;
            }
        }

        return answer;
    }

마지막 조건에서 -1이 아니라 488이 나오는 문제 발생

  • if (a % 2 == 0)if (a % 2 != 0)이 둘 다 독립적인 if문으로 되어 있어서,
  • 짝수 조건에서 나누고 break가 걸리지 않으면, 바로 아래 홀수 조건도 다시 실행돼어버린다.

예)
a = 6
→ 짝수라서 /2 → a = 3, answer = 1
→ 다음 if: 3은 홀수니까 *3+1 → a = 10, answer = 2
원래는 6 → 3이어야 하는데, 한 턴에 6 → 3 → 10 으로 두 칸을 건너뛰어버림.

  • 콜라츠 수열은 이전 값에 따라 다음 값이 결정돼야 함.

  • 근데 하나의 루프에서 2번 계산되면 수열이 깨져버림.

수정 코드

public static int solution(int num) {
    int answer = 0;
    long a = num; 
    while (a != 1) {
        if (a % 2 == 0) {
            a /= 2;
        } else {
            a = a * 3 + 1;
        }

        answer++;

        if (answer >= 500) {
            return -1;
        }
    }

    return answer;
}
  • int로 하면 오버플로우 발생 위험 있으니 long으로 변경
  • if / else 구조로 만들어 한 번에 하나의 연산만 수행하도록 변경
  • answer++ 공통으로 한 번만 증가 하도록 변경.

for문 + 삼항 연산자

public static int solution(int num) {
        long a = (long) num;

        for (int i = 0; i <= 500; i++) {
            if (a == 1) {
                return i;
            }
            a = (a % 2 == 0) ? a /2 : a * 3 + 1;
        }
        return -1;
    }
  • 오버플로우 방지 long n = (long)num; — 안전하게 처리
  • 반복 횟수 제한 i < 500 — 조건 정확
  • 빠른 종료 if(n == 1) return i; — 성능도 좋다.
  • 가독성 3항 연산자 사용으로 코드 짧고 명확
  • 표준 로직 문제 조건에 딱 맞음

0개의 댓글