Bin's Blog

[프로그래머스] Level2 - 2개 이하로 다른 비트(Javascript) 본문

Algorithm

[프로그래머스] Level2 - 2개 이하로 다른 비트(Javascript)

hotIce 2023. 4. 27. 09:49
728x90
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

▶ 문제 요약

1. 양의 정수 x에 대한 함수는 x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수 

2. 정수들이 담긴 배열이 매개변수로 주어질 때 모든 수들에 대해서 각 수의 f값을 배열에 차례대로 담아 return 

▶ 코드

function solution(numbers) {
     let answer = [];
     function check(n) {
       // n이 짝수이면 다른 비트의 개수가 1개이니 n+1 반환
       if (n % 2 === 0) return n + 1;
       
       // 홀수면 앞에 0 붙여주고 이진수로 변환
       n = "0" + n.toString(2);
       // 가장 오른쪽에 있는 0을 찾는다.
       let idx = n.lastIndexOf("0");
       
       // 오른쪽에 있는 0까지 slice + "10" + idx+2개 이후 slice
       // 그리고 정수변환
       return parseInt(n.slice(0, idx) 
              + "10"
              + n.slice(idx+2), 2);

    
    
     }
     // 입력값을 차례대로 함수에 넣는다.
     numbers.forEach(n => answer.push(check(n)));
	
    
     return answer;



}

▶ 풀이 과정

1. 반복적인 연산을 처리하기 위해 함수를 만든다. 

 

2. n이 짝수면 n+1를 반환하는 이유는 문제 설명을 보면 알 수 있다. 2와 3의 다른 비트의 개수는 1개다. 8과 9도 다른 비트의 개수는 1이며 10과 11의 다른 비트의 개수는 1개다. 그래서 짝수는 n+1에서 다음 수를 리턴하면 된다.

 

3. 그림을 먼저 보겠다.

위에 그림을 보면 홀수인 경우가 중요하다. 입력값 7을 이진수로 변환하면 문제 설명에 나온 0111가 아닌 111이 된다. 그래서 앞에 0을 붙여준다. 문제 설명을 보면 f(7) = 11인데 뜯어보면 7은 "0111"이고 11은 "1011"이다. 이렇게 만드려면 01 부분을 10으로 바꾸고 나머지 수를 붙여줘야한다. 그래서 0의 마지막 인덱스를 찾아서 그 부분까지 slice를 해주고 "10"을 더해주고 그리고 앞에 2개의 수를 더했으니 2개의 수를 제외한 그 나머지 부분을 더해주면 된다. 최종적으로 "1011"이 된다.

 

하나 예시를 더 보겠다 f(13)인 경우 이진수로 변환하면 1101이기 때문에 앞에 0을 붙여준다. 그러면 01101이 된다. 거기서 마지막 0은 인덱스상 3에 해당한다. 그러면 거기까지 slice해주면 "011"이 나오며 뒤에 "10"을 붙여주면 "01110"이 되고 idx+2를 하면 인덱스 5인데 인덱스는 4까지 존재하므로 없는 값이다. 따라서 "01110"이 된다. 

 

4. 값을 구했으면 parseInt()함수를 통해서 문자열을 2진법으로 읽어서, 10진법으로 변환한 값을 리턴해준다.

 

5. 마지막으로 주어진 입력값을 forEach() 메서드를 활용해서 안의 요소를 돌면서 위에 만들었던 함수를 실행한 값을 배열에 넣어주고 리턴하면 정답이 출력이 된다.

 

▶ 배운점

1. 이런 문제는 패턴을 빨리 찾아야 풀 수 있다. 그래서 어떻게 주어진 값을 빠르게 변환시킬 것인지 고민을 먼저 해야한다. 

2. 문제를 더 작은 단위로 쪼개서 풀자.

728x90