※ 본 사진과 해당 게시글 내용의 문제 모두 프로그래머스[Programmers]사이트에 발췌해왔습니다.

💬 들어가기 앞서..

💢 콜라츠 추측(Collatz conjecture) 란?

3n+1 추측, 울람 추측, 혹은 헤일스톤(우박) 수열 등 여러 이름으로 불린다.

"임의의 자연수가 다음 조작을 거쳐 항상 1이 된다." 라는 추측

  • 짝수라면 2로 나눈다.
  • 홀수라면 3을 곱하고 1을 더한다.
  • 1이면 조작을 멈추고, 1이 아니면 첫 번째 단계로 돌아간다.

이 추측은 컴퓨터로 2^68 까지 모두 성립함이 확인되었다고 한다...
그러나, 아직 모든 자연수에 대한 증명은 부족하다고 한다.


※ 출처 ㅣ 위키백과_콜라츠 추측


❓ 문제

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을 완성해 주세요.
단, "작업을 500번을 반복해도 1이 되지 않는다면" –1을 반환해 주세요.

제한 조건 :
입력된 수, num은 1 이상 8000000 미만인 정수입니다.

입출력 예
n	|	result
6	|	8
16	|	4
626331	|	-1

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

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

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

❗ 풀이

My Code

def solution(num):
    i = 0
    if num == 1 :
        return i
    while True:
        if i == 500 :
            answer = -1
            break
        if num == 1:
            answer = i
            break
        if num % 2 == 0 :
            num = num/2
        else :
            num = (num*3) + 1
        i += 1
    return answer

알고리즘을 짜고 나니 코드가 너무 긴 느낌이 든다...😂
우선 제한조건에서 입력값이 1 이상 이라는 조건이 있기 때문에
반환값이 될 반복값을 의미하는 임의의 변수 i에 0을 대입해주고
IF문으로 "입력값 num이 1일 때" 반복을 하지 않았으니 바로 0인 i값을 return하게끔 작성하고

While True를 활용해 루프문을 작성해주었다.
처음에 선언했던 변수 i를 반복할 때마다 1을 더해주는 i += 1이라는 수식을 넣어준다.

제한 조건에 따라 두 경우의 Break문 조건을 걸어주었다.
500번을 반복했을 때 return값 answer에 -1을 주고 break하는 경우와
반복 끝에 1이 되었을 때 answeri(반복횟수)을 대입하고 break하는 경우이다.

반복될 계산 작업엔 break를 주지 않게끔 작성하여 완성한다.

❣ 다른 풀이

(1)

def collatz(num):
	if num == 1:
    	return 0
    for i in range(500):
        num = num / 2 if num % 2 == 0 else num*3 + 1
        if num == 1:
            return i + 1
    return -1

우선 제한 조건을 고려하여 For문을 사용한 경우인데
반복문에 들어가기 전에 입력값이 1일 경우에 0을 Return하게끔 먼저 작성하고
For문에서는
원라인(One-Line) if~else문을 작성하여 계산하고 num변수에 재대입하며
range(500) 범위 반복 내에서 num이 1이 뒬 경우
시작값 0이여서 1회는 i가 0인 점을 감안하여 반복횟수인 i+1을 반환다.

마지막에 range(500)을 넘어간 경우엔 -1을 반환하게끔 하였다.


0개의 댓글