파이썬 주어진 두 입력값을 이진수로 바꾸어 비교하는 문제

조회수 384회

w1과 w2는 각 수를 이진수로 바꾸었을 시의 1의 개수이고, d는 두 수를 비교했을 시의 같은 자리 수에서 각각 0과 1이 따로 나오는 개수입니다.

최대한 풀었고 답도 맞는 것 같는데 어딘가 틀렸다고 하네요. 혹시 도와주실 수 있으면 부탁드립니다.

testcase= int(input())
for i in range(testcase):
    num1, num2 = map(int, input().split())
    b1 = int(bin(num1)[2:])
    b2 = int(bin(num2)[2:])
    s1 = bin(num1)[2:]
    s2 = bin(num2)[2:]
    ans1 = 0
    ans2 = 0
    while b1 :
        b1 //= 10
        ans1 += 1
    while b2 :
        b2 //= 10
        ans2 += 1
    w1 = 0
    w2 = 0
    d = 0
    for j in range(ans1):
        if s1[j] == '1' :
            w1 += 1
    for k in range(ans2):
        if s2[k] == '1' :
            w2 += 1
    while ans1 > ans2 :
        s2 ='0' + s2
        ans2 += 1
        if ans1 == ans2 :
            for l in range(ans1):
                if s1[l] != s2[l]:
                    d += 1
    while ans2 > ans1 :
        s1 ='0' + s1
        ans1 += 1
        if ans1 == ans2:
            for m in range(ans1):
                if s1[m] != s2[m]:
                    d += 1
    print(w1,w2,d, sep=" ")
  • 열심히 풀었네요. 비트연산에 대해 공부하면 좀 더 효율적으로 짤 수 있습니다. nowp 2022.6.2 10:27

1 답변

  • 작성해 주신 코드 자체를 들여다보기는 좀 어렵군요. (제 능력이 부족해서...) 그래서 그냥 새로 작성해 봤어요.
    문제에서 딱히 제한하고 있지 않은 듯하여 비트 AND 연산을 써도 된다고 가정하고 풀어봤는데요.

    # "코드 실행하기"로 바로 실행해볼 수 있습니다.
    num1 = 1
    num2 = 17
    print(int(bin(num1)[2:]), int(bin(num2)[2:]), sep = ' / ') # 이진수 변환은 여기서만 한번 해보고 실제 처리에서는 안씁니다.
    
    w1 = 0
    w2 = 0
    d = 0
    digit = 1
    while digit <= num1 or digit <= num2 :
        num1ThisDigitEquals1 = bool(num1 & digit) # num1의 이번 자릿수와 digit을 bit and 비교
        num2ThisDigitEquals1 = bool(num2 & digit)
        print(num1ThisDigitEquals1, num2ThisDigitEquals1, sep = ' vs ')
        if (num1ThisDigitEquals1) :
            w1 += 1
        if (num2ThisDigitEquals1) :
            w2 += 1
        if (digit <= num1 and digit <= num2 and num1ThisDigitEquals1 != num2ThisDigitEquals1) :
            d += 1
        digit *= 2
    print(w1, w2, d, sep = ' / ')
    

    질문자님의 코드는 num1num2 각각에 대해 뭔가 카운팅을 하는 모양이고, 제 코드는 둘을 맞다이 붙여 비교합니다. 아무튼 그렇게 풀어보니, 아무래도 num1num2의 이진 변환 자릿수가 다를 때 문제가 될 듯합니다.


    위 코드를 보시면 쓸데없이 길어 보이는 조건절이 있을 거에요.

    if (digit <= num1 and digit <= num2 and num1ThisDigitEquals1 != num2ThisDigitEquals1) :
    

    이게 이래 보여도 필요한 조건입니다. 왜냐면 현재의 while 루프는 "num1이든 num2든 양쪽다 디지기 전까지는 묻고 다음 자릿수로 가!" 하고 있거든요. 그런데 두 숫자의 자릿수를 각각 비교하려면 둘 다 그 자릿수만큼은 큰 숫자여야 하잖아요. 둘 중 하나라도 그 자릿수만큼 크지 않으면, 뒤집어서 비교할 자릿수가 없는 거니까, 광팔고 죽어야 되는 거구요.

    그래서 저 비교 조건이 추가로 필요해요. 한쪽 숫자가 너무 작아서 다음 자릿수를 차마 비교할 게 없을 경우,

    if (num1ThisDigitEquals1 != num2ThisDigitEquals1) :
    

    이것만 갖고 판별하면, d값이 마지막에 한 번 더 올라가는 버그가 나는 거 같습니다. 위 코드의 1 vs 17의 경우, d값의 정답은 0이어야 하는데, 저대로 실행하면 1이 됩니다.


    이상의 접근 및 관찰이 현재 질문자님의 코드와 어떤 관계가 있는지, 애초에 관계가 있긴 한지 등등은 사실 잘 모르겠긴 합니다. 그냥 해보니 이렇더라 정도로만 이해해 주시고, 한번 다시 차분히 살펴보세요. 참고가 되면 좋겠네요.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)