코딩테스트/프로그래머스 기초 트레이닝

[Javascript] 1로 만들기 (+답변 추가)

dev_swH 2023. 6. 28. 23:07

문제 설명 : 

정수가 있을 때, 짝수라면 반으로 나누고, 홀수라면 1을 뺀 뒤 반으로 나누면, 마지막엔 1이 됩니다.

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

 

첫 풀이 :

로직 과정은 분명히 맞는 것 같은데 자꾸 답이 7로 나온다.

한 번씩 카운트를 덜한다는 소리 같은데, 왜 그렇게 되는지 도무지 원인을 찾지 못했다...

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

 

결국 구글링으로 찾아서 아래처럼 풀기는 했는데 여전히 어디에 차이가 있는지 모르겠다.

function solution(num_list) {
    let count = 0;
    
    for (const el of num_list) {
        let num = el;

        while (num !== 1) {
          if (num % 2 === 0) {
            num /= 2;
          } else {
            num -= 1;
            num /= 2;
          }
            count++;
        }
    }
    
    return count;
}

 

그러다 다른 사람의 풀이에서 나의 첫 풀이와 유사한 답안을 찾아냈다.

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);
}

 

위 답안을 참고해서 첫 풀이를 이렇게 저렇게 수정해봤더니 드디어 테스트에 통과했다!!!

아래가 최종 코드.

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

 

근데 문제는.......왜 이렇게 수정해야 7이 아니라 11이 나오는지...이해하지 못했다ㅠㅠ..............ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

혹시나 누군가 도와줄까 싶어서 일단 프로그래머스에 질문을 남겨봤다.

 


오늘 아침 상냥한 분께서 답변을 달아주셨다!!!!!

즉 나의 첫 코드는 cur을 조건에 따라 연산한 값을 return하여 그걸 누적값에 매번 넣게 되는 로직이었다.

acc++는 그냥...무시당한 거구나....😂

첫 코드에서 반환값이 7이 나오는 이유는, acc가 한 번씩 덜 증가하는 것이 아니고

그냥 마지막 원소값이 14여서 14 / 2를 한 7이 acc에 들어간 것이었다.

 

생략해서 짧고 가독성 높은 코드에 익숙해져서

그간 return을 제대로 이해하지 못하고 무작정 코드를 써왔다는 생각이 들었다.

반성.