[Review] 월간 코드 챌린지 시즌2 2차 2번 - 2개 이하로 다른 비트

2개 이하로 다른 비트 - Level 2

https://programmers.co.kr/learn/courses/30/lessons/77885


짝수 => 맨 마지막 비트 하나만 바꾸면 됨
홀수 => 맨 앞 비트 하나와 그 다음 1의 자리


My Answer 1

def solution(numbers):
    answer = []
    
    for i in range(len(numbers)):
        if numbers[i] % 2 == 0:
            answer.append(numbers[i] + 1)
        else:
            base = list(str(bin(numbers[i])))[2:]
            tmp = numbers[i]
            if "0" not in base:
                answer.append(numbers[i] + 2**(len(base)-1))
            else:
                while True:
                    tmp += 1
                    t = list(str(bin(tmp)))[2:]
                    cnt = 0 
                    for j in range(len(t)):
                        if t[j] != base[j]:
                            cnt += 1
                    if cnt < 3:
                        answer.append(int(''.join(t), 2))
                        break
            
    return answer

당시.. 문제 풀때...
2 의 배수를 더하고 어떻게 하면 될 거 같은데 계속 안됐다...

계산을 잘못했기 때문^^

그래서 일단 비효율적이어도 노가다로 돌려보니까 됐다..ㅠ

numbers[i] 에 1 씩 더해가면서 원래 값과 비트가 다른 갯수를 카운트 해줌

2번에 올인하느라 시간 날림 xx^^

My Answer 2

def solution(numbers):
    answer = []
    
    for i in range(len(numbers)):
        if numbers[i] % 2 == 0:
            answer.append(numbers[i] + 1)
        else:
            base = list(str(bin(numbers[i])))[2:]
            tmp = list(str(bin(numbers[i])))[1:]
            tmp[0] = "0"
            cnt = 0
            t = 0
            tmp2 = ["1"]
            if "0" not in base:
                answer.append(numbers[i] + 2**(len(base)-1))
            else:
                for j in range(len(tmp)-1, -1, -1):
                    if tmp[j] == "0":
                        t = j
                        break
                    else:
                        tmp[j] = "0"
                        tmp2.append("1")
                tmp2[1] = "0"
                answer.append(int(''.join(tmp), 2) + int(''.join(tmp2), 2))
                
            
    return answer

원래 하던 방식을 수정해서 돌린 것.. 수학적으로..

1 이 연속되는 부분만 잘라서 처리해주고 원래 앞부분과 합해준다

런타임 제한 없이 빠르게 돌아감


비트 연산 이용

Answer 1

def solution(numbers):
    answer = []
    for number in numbers:
        if number & 1:
            target = number
            idx = 0
            while number > 0:
                if number % 2 == 0:
                    break
                number //= 2
                idx += 1
            answer.append(target + 2 ** (idx) - 2 ** (idx-1))
        else:
            answer.append(number+1)

    return answer

if number & 1: => 맨 마지막 자리가 1 인지 판단해서 True 면 홀수이므로
다음으로 1 인 자리 찾아서 (idx)
number 에 자리에 해당하는 값(2 ** (idx) - 2 ** (idx-1))을 더해주기
else => 짝수이므로 +1

Answer 2

def solution(numbers):
    answer = []
    for val in numbers:
        answer.append(((val ^ (val + 1)) >> 2) + val + 1)

    return answer

그냥 천재같다...

좋은 웹페이지 즐겨찾기