[Level2] 2개 이하로 다른 비트




2개 이하로 다른 비트

프로그래머스

틀린 코드

function solution(numbers) {
  const answer = [];
  let flag;
  let j;
  for (let i = 0; i < numbers.length; i++) {
    flag = true;
    let temp = numbers[i].toString(2).split('');

    for (j = temp.length - 1; j >= 0; j--) {
      if (temp[j] == '0') {
        temp[j] = '1';
        flag = false;
        break;
      }
    }
    if (!flag) {
      for (let i = temp.length - 1; i > j; i--) {
        if (temp[i] == '1') {
          temp[i] = '0';
        }
      }
    } else {
      temp[0] = '0';
      temp.unshift('1');
    }

    answer.push(parseInt(temp.join(''), 2));
  }
  return answer;
}

에제는 통과 됐는데, 제출문제는 모든 것이 오류가 났다.
테스트케이스를 알 수 있으면 좋을텐데 도저히 어디가 문제인지를 찾지 못했다.ㅠ



정답 코드

function solution(numbers) {
  const answer = [];

  for (let i = 0; i < numbers.length; i++) {
    let temp = [...numbers[i].toString(2)];
    if (temp[temp.length - 1] == 0) temp[temp.length - 1] = 1;
    else if (temp.lastIndexOf('0') !== -1) {
      let lastIndex = temp.lastIndexOf('0');
      temp[lastIndex] = '1';
      temp[lastIndex + 1] = '0';
    } else {
      temp[0] = '0';
      temp.unshift('1');
    }

    answer.push(parseInt(temp.join(''), 2));
  }
  return answer;
}

접근 방식의 문제점을 깨달았다.
3가지의 경우로 나눠야하는데

  1. 마지막 문자가 0인 경우 > 1로 바꿈
  2. 중간에 0이 나오는 경우 > 1로 바꾸고 바로 뒤에 수를 0으로 바꿈
  3. 모든 게 1인 경우 > 1을 맨 앞에 추가하고 2번째 값(기존 첫번째)를 0으로 바꿈


비트를 2개만 수정해야하는 제약이 있었는데, 이걸 잊고 2번의 경우 뒤에 모든 수를 0으로 바꾸고 있었다.
또 가독성을 높이기 위해 for문으로 2번에서 0을 찾는 과정을 lastIndexOf로 수정하였다.