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

김유원·2024년 1월 16일
0

📝24.01.16

🔗 문제 : https://school.programmers.co.kr/learn/courses/30/lessons/12943

문제 설명

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

[C#] 내가 작성한 풀이

이 문제의 핵심은 주어진 숫자의 범위이다. int의 범위가 -2,147,483,648 ~ 2,147,483,647 이므로, 만약 해당 과정에서 num이 지속적으로 홀수인 경우가 발생하다보면 범위를 벗어나는 경우가 발생하는 것이다.

따라서 나는 그래서 그냥 solution 함수의 매개변수num을 long으로 바꿔주는 방식으로 풀이했다.

public class Solution {
    public int solution(long num) {
        int answer = 0;
        
        while(num != 1) {
            if(++answer > 500) return -1;
            num = (num % 2 == 0) ? num / 2 : (num * 3) + 1;
        }
        
        return answer;
    }
}

[C++] 내가 작성한 풀이

C#과 다른 점이라면 numint 그대로 받아 long temp라는 임시 변수에 암시적 형 변환을 진행하여 풀이한 것 하나다.

#include <string>
#include <vector>

using namespace std;

int solution(int num) {
    int answer = 0;
    
    long temp = num;
    while(temp != 1) {
        if(++answer > 500) return -1;
        temp = (temp % 2 == 0) ? temp / 2 : temp * 3 + 1;
    }
    return answer;
}

[C#, C++] 남이 작성한 풀이

어김없이 비트 연산자를 활용한 풀이도 눈에 들어온다. 이제 2배나 1/2배의 경우 << 1과 >> 1로 풀이할 수 있다는 사실은 확실히 각인되었다. 하지만 n & 1 이 부분이 다소 생소하여 생각해보았다.

이 식은 n이 홀수라면 n의 마지막 비트가 1일 것이고 이를 1과 비교하여 만약 마지막 비트가 1이 맞다면 true가 반환될 것이니 홀수, 1이 아니라면 false가 반환될 것이니 짝수라는 것을 표현한 식이다. 내가 작성한 삼항 연산자를 거의 동일하게 비트 연산으로만 풀이한 식이라고 볼 수 있다.

int solution(int num) {
    long long n = num;
    for(int i = 0; i < 500; i++) {
        if(n == 1) return i;
        n = (n & 1) ? (n * 3 + 1) : (n >> 1);
    }
    return -1;
}
profile
개발 공부 블로그

0개의 댓글

관련 채용 정보