프로그래머스Lv2 - 2개 이하로 다른 비트

요리하는코더·2021년 8월 25일
0

알고리즘 - 문제

목록 보기
17/48
post-thumbnail

코드

function solution(numbers) {
    var answer = [];
    
  // 참고 input output
    // input [1001, 337, 0, 1, 333, 673, 343, 221, 898, 997, 121, 1015, 665, 779, 891, 421, 222, 256, 512, 128, 100]
    // output [1002, 338, 1, 2, 334, 674, 347, 222, 899, 998, 122, 1019, 666, 781, 893, 422, 223, 257, 513, 129, 101]
 
    numbers.map((number) => {
        const two = number.toString(2).split('').reverse().join('');
        const idx = two.indexOf(0)
        if(idx === -1) {
            const ten = parseInt(('10' + two.slice(1)),2);
            answer.push(ten);
        }
        else {
            if(two[idx-1] == 1) {
                let modify = two.split('');
                modify[idx] = 1;
                modify[idx-1] = 0;
                const ten = parseInt(modify.reverse().join(''),2)
                answer.push(ten)
            }
            else if(two[idx+1] == 0) {
                let modify = two.split('');
                modify[idx] = 1;
                const ten = parseInt(modify.reverse().join(''),2)
                answer.push(ten)
            }
            else if(two[idx+1] == 1) {
                let modify = two.split('');
                modify[idx] = 1;
                const ten = parseInt(modify.reverse().join(''),2)
                answer.push(ten);
            } else if(two[idx] == 0) {
                let modify = two.split('');
                modify[idx] = 1;
                const ten = parseInt(modify.reverse().join(''),2)
                answer.push(ten);
            }
        }
    })
    
    return answer;
}
def solution(numbers):
	return [findN(x) for x in numbers]
    
def findN(n):
	bits = [0, 1, 2]
    
    t = n
    idx = 0
    while True:
    	v = t % 4
        if v in bits: #00, 10
        	return n + (1 << idx)
        t >> 1
        idx += 1

풀이 및 소감

위의 Javascript 코드는 내가 짠 코드이고 아래 bit 연산자를 쓴 것은 친한 형이 쓴 코드이다.
먼저 이 문제를 풀때 생각한 것은 4가지 경우가 있다고 생각했다.(사실은 5가지)

  1. 모두가 1인경우 => 맨앞에 10을 붙여주면 됨
  2. 중간에 00이 있는 경우 => 가장 뒤에 등장하는 00을 01로 바꿔주면 된다.
  3. 중간에 01이 있는 경우 => 가장 뒤에 등장하는 01을 10으로 바꿔주면 된다.
  4. 중간에 10이 있는 경우 => 가장 뒤에 등장하는 10을 11로 바꿔주면 된다.
  5. 내가 빼먹었던 0인 경우 => 1로 바꿔주면 된다.

이렇게 로직을 짜고 구현을 했는데 너무 복잡하게 한 거 같다... 먼저 2진수로 바꾸고 뒤집기위해 split, reverse, join을 사용했다. 그리고 0이 하나도 없는 경우에 먼저 10을 붙여주었고 그 다음 내가 위에 작성한 경우를 파악하는데 일단 0이 존재하는 곳을 찾았다. 그리고 여기서 또 순서를 신경써야하는데 11001이면 0001로 바꾸는 것보다 0110으로 바꾸는 게 값이 더 작다. 만약 11011인 경우에도 0111로 바꿔야한다. 1000은 무조건 0001로 바꿔주는 게 더 작다. 5번은 문제에서 양의 정수라해서 신경 안 쓰고 있었는데 포함되는 거 같다... 로직은 나름 빨리 생각한 거 같은데 구현에서 오래걸렸다ㅠㅠ

다음으로, 파이썬 코드를 작성한 형의 설명을 조금 추가하자면 t % 4는 비교해야할 비트 2개를 가져온 것 이라고 했다. 그리고 비트 연산자를 활용해서 문제를 해결했다. 간결하게 구현을 잘 한 거 같은데... 나도 이렇게 깔끔하게 코드를 짤 수 있으면 좋겠다.

profile
요리 좋아하는 코린이

0개의 댓글