우당탕탕 개발일기

[프로그래머스 / 자바스크립트] 콜라츠 추측 본문

What I Learned/Algorithm

[프로그래머스 / 자바스크립트] 콜라츠 추측

rilee 2022. 1. 24. 15:57
728x90

처음으로 도움이 되지 않았던 입출력 예...

비문학같았지만, 차근차근 정리해보니 수식 몇 개와 조건문 몇 개로 나누어지는 것을 알 수 있었다.

일단 작업에 있는 조건들을 다 if문으로 정리를 했고, for문으로 500까지 반복해야 할 것이라 생각했다.

 

그리고 일단 그냥 정리한것을 토대로 코드를 작성해보았다.

 

(⚡️엉망코드)

function solution(num) {
    var answer = 0;
    for (var i = 0; i<500; i++){
        if (num[i] % 2 == 0) {
            answer += num / 2
        } else if (num[i] % 2 !== 0) {
            answer += num * 3 + 1
        } else if (num[i] == 1) {
            break;
        }
    }
    return answer;
}

엄청난 결괏값과 함께 당연히 실패가 떴다ㅎ!

 

짝수 / 홀수 / 결과가 1이 되는 경우를 어떻게 구분해야 할 지 판단이 서지않았다.

break가 illegal하다고 뜨질 않나,, 근데 지금 보니 while문 아닌데 왜 break 넣은 탓이네ㅠ;

아무튼 나의 첫 시도가 와장창 되고 while문을 사용하시는 분들도 많길래 while문에 대해 검색했다.

 

while문의 기본형태는, 

while ( 조건문 ) {
	( 실행문 ) //실행문이 한 줄이라면 {} 생략하고 ( 조건문 ) 옆에 붙일 수도 있다!
    }

이렇게 이루어져있다.

 

for문은 범위가 지정되므로 (ex. i=0; i<n.length;) "반복 횟수를 정할 수 있을 때" 주로 사용되고,

while문은 조건문만 있으므로 "몇 번 반복되는 지 모를 때" 주로 사용된다고 한다.

 

이 때 주의할 점은 while문은 조건문밖에 없으므로 조건문의 값이 true일 경우 무한으로 while문이 돌아간다는 것.

이렇게 되면 프로그램이 메모리 초과 및 cpu 과부하로 꺼질 수 있어서

break 조건문으로 일정 조건에서 멈춰줘야 하는 것을 꼭 기억해야한다! 

 

몇 번 반복되는지는 도출해야하는 결과 값이니까 '몇 번 반복될 지 모른다'고 생각한 나는 while문으로 코드를 작성했다.

function solution(num) {
    var count = 0;
    
    while (num != 1){
        num = num % 2 == 0 ? num / 2 : num * 3 + 1
        count ++;
        if (count >= 500)
            return -1;
    }
    return count;
}

이것도 일단은 성공..💡 근데 while이 아직 익숙하지 않은 탓에 알쏭달쏭하다

 

.

.

.

 

💡 나의 최종 코드

function solution(num) {
    var answer = 0;
    
    for (var i = 0; i < 500; i++){
        if(num !== 1) num = (num % 2 == 0) ? num / 2 : num * 3 + 1
        else return answer = i
    }
    return answer = -1
}

 

처음 for문 사용했을 때 오류는 내 답안이 오류였기 때문에, 처음에 썼던 for문을 다시 사용해서 i의 범위를 확실하게 정했다.

자연스럽게 for문으로 i가 500 미만인지 500 이상인지를 구분이 된다. (for문 - return answer -1)

 

그 다음은 바로 짝수/홀수가 아니라, num이 1이 아닌 경우와 1인 경우로 나누었다.

cf. if / else를 사용할 땐 조건의 true값이 더 많은 쪽을 If로 사용해야 한다! 여기선 num이 1이 아닌 경우가 훨씬 많으므로 if문 당첨!

 

그 다음이! num이 1이 아닌 경우 '중'에서 짝수/홀수를 구분하고, num이 1이면은 횟수인 i를 리턴하는 것.

 

여러가지 조건을 어떻게 정리해야하나가 초반에 머리아프게 하던 원인이었는데,

조건이 여러가지인 경우 어떤 조건이 더 우선이 되는지를 잘 따져봐야겠다.

 

이건 다른 분의 while문을 이용한 코드.

while문에서 조건을 1️⃣ num이 1이 아니라는 것, 2️⃣ 반복 횟수(answer)가 500이 아니라는 것을 동시에 주고 시작했다.

그리고 삼항 연산자를 이용해 짝수/홀수를 구분했고,

answer가 증가하게끔 answer++;를 while문 안 + 조건문 바깥에서 딱 한 번.

while문을 빠져나와 num이 1인지 여부를 따져 true면 answer값, false면 -1을 주었다.

 

마지막 코드가 조금 헷갈려서 이해하는게 어려웠다.

마지막 코드는 while문을 조건하에 돌고 있는데, num이 1이 되면 answer값을 리턴하고,

1이 되지 않으면 즉, answer ++; 가 499를 지나도 1이 아니면 -1을 리턴하는 뜻으로 생각한다.

 

조건문은 진짜 단순하게 짤 게 아니라는 생각이 빡,,

 

 

💪🏻 느낀 점

  • 코드를 볼수록, 어쩌면 쉽게 풀 수 있는 문제였는데 내 힘으로 끝마치지 못한게 분하고 아쉽다,,🔥
    '반복 되는 횟수를 리턴'하는 것에 꽂혀서 조건문을 이것저것 도전해 볼 생각을 미처 하지 못했다. 뭐,, 완벽한 실력 부족,, 
  • 그동안 그렇게 for문과 if문을 사용하면서 어느 정도 감을 잡았다고 생각했는데 뒤통수를 씨게 맞은 기분..
    내가 아는 걸로 충분히 풀 수 있는 문제였는데, 처음에 조건문의 갈피를 잘못 잡은게 주 요인이라고 생각한다.
    초반 문제 푸는 계획의 중요성을 다시 한 번 깨닫게 된 문제.
  • 그래도 while문, 조건문의 반복 등에 대해서 찾아볼 수 있는 시간이었다,, 🥲

  • 다음에는 절대 틀리지 않으리,,🔥

 

 

📍 문제 출처

: https://programmers.co.kr/learn/courses/30/lessons/12943

 

코딩테스트 연습 - 콜라츠 추측

1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다. 1-1. 입력된 수가 짝수라면 2

programmers.co.kr

 

728x90