[프로그래머스-기초] 1로 만들기

JiEun·2024년 1월 18일
0

코테/코플릿

목록 보기
51/56

1로 만들기

문제 설명

정수가 있을 때, 짝수라면 반으로 나누고, 홀수라면 1을 뺀 뒤 반으로 나누면, 마지막엔 1이 됩니다. 예를 들어 10이 있다면 다음과 같은 과정으로 1이 됩니다.

10 / 2 = 5
(5 - 1) / 2 = 4
4 / 2 = 2
2 / 2 = 1
위와 같이 4번의 나누기 연산으로 1이 되었습니다.

정수들이 담긴 리스트 num_list가 주어질 때, num_list의 모든 원소를 1로 만들기 위해서 필요한 나누기 연산의 횟수를 return하도록 solution 함수를 완성해주세요.

제한사항

3 ≤ num_list의 길이 ≤ 15
1 ≤ num_list의 원소 ≤ 30

입출력 예

num_listresult
[12, 4, 15, 1, 14]11

입출력 예 설명

입출력 예 #1
12는 3번, 4는 2번, 15는 3번, 1은 0번, 14는 3번의 연산이 필요하기 때문에 총 11번의 연산이 필요합니다.

내가 작성한 코드

function solution(num_list) {
    let result = 0;
    
    for(let i = 0; i < num_list.length; i++){        
        while(num_list[i] > 1){
            let num = 0;
            if(num_list[i] % 2 === 0){
                num = num_list[i] / 2
                result += 1
            } else {
                num = (num_list[i] - 1) / 2
                result += 1
            }
            num_list[i] = num
        }        
    }   
    return result 
}

해당 문제에서 중요하 점은 값이 정수인지 음수인지에 따라 반환하는 값이 다르다는 점이다.
또한 1이 될 때까지 나눠줘야하는데 이점을 봤을 때 while문을 사용하면 되겠다는 생각을 했다.

for문을 이용해 num_list를 순환하고
while문의 조건으로 num_list[i]가 1보다 클 때 까지 순환한다.

나눈 값을 담을 num을 선언해 주고
num_list[i]가 정수 인지, 음수인지에 따라 조건을 다르게 작성해 주었다.

이 때 한 번 연산이 이루어 질 때 마다 result에 1을 더해 줬다.

마지막으로 num_list[i]에 연산된 값으로 재 할당해 주므로써 원하는 값을 얻을 수 있었다.

초반에 num_list[i] = num 연산된 값으로 재 할당하지 않아
num_list[i] > 1 조건이 충족되지 않아 무한 루프에 걸렸었다.

이번 시간에 while에 대해 다시 공부하게 된 것 같다.

코드 리팩토링 하기

function solution(num_list) {
    let result = 0;
    
    for(let i = 0; i < num_list.length; i++){        
        while(num_list[i] > 1){            
            let num = num_list[i] % 2 === 0 ? num_list[i] / 2 : (num_list[i] - 1) / 2
            result += 1
            
            num_list[i] = num
        }        
    }
    return result 
}

if문 대신 삼항연산자를 사용했다. 삼항연사자는 바로 값이 될 수 있다.

이 점을 이용해 num에 바로 값을 할당했다.
이로서 불필요한 코드를 줄일 수 있었다.

프로그래머스는 forEach, map, filter, reduce 메소드 내부에 다른 변수 등을 넣을 수 없는지 알 수 없다...

이번 문제도 for문 대신 forEach나 map메소드로 작성했다면 좀 더 간결하게 작성할 수 있었을 것 같다.

다른 사람이 작성한 코드

function solution(num_list) {
    return num_list.map(v => v.toString(2).length - 1).reduce((a, c) => a + c);
}

toString()을 통해 이진수로 만들어서 푸셨다.
이분은 진짜 대단한 것 같다...

function solution(num_list) {
  return num_list.reduce((acc, cur) => {
    let count = 0;
    while (cur !== 1) {
      cur = cur % 2 ? (cur - 1) / 2 : cur / 2;
      count++;
    }
    return acc + count;
  }, 0);
}

이분은 reduce로 작성하셔서 가지고 왔다.

코드 보는 눈을 많이 길러야겠다.

profile
💻 프론트엔드를 목표로 성장 중! (알아봤던 내용 등을 정리하기)

0개의 댓글