'파이썬 알고리즘 인터뷰(박상길, 책만)' 참조

1. 문제 - 비밀 지도

  • 네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.
    • 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.
    • 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 "지도 1"과 "지도 2"라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
    • "지도 1"과 "지도 2"는 각각 정수 배열로 암호화되어 있다.
    • 암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.
    image
- 입력: 
  - n = 5
  - arr1    [9, 20, 28, 18, 11]
  - arr2    [30, 1, 21, 17, 28]
- 출력    ["#####","# # #", "### #", "# ##", "#####"]

 

2. 풀이 - 이진수 OR 연산

1) OR 연산

비트 연산자 OR를 이용하여 이진수를 계산하는 문제다.

두 개의 지도를 합칠 때, 둘 중 하나라도 벽(’#)이면 벽(’#)이 나오고,

둘 중 모두가 공백(” “) 일 경우에 공백(” “)이 나온다.

‘이진수 1’을 벽(’#’)으로, ‘이진수 0’을 공백(” “)으로 치환하면 된다.

하나의 지도가 10100(2), 다른 지도가 00001(2)라고 할 때,

두 이진수를 OR(|) 연산하면 10101(2)이 된다. 각 자릿수를 계산해보면 쉽게 이해가 될 것이다.

 

for i in range(len(arr1):
    bin_or = bin(arr1[i] | arr2[i])[2:].zfill(len(arr1))

 

bin() 매서드를 사용해서 십진수를 이진수로 바꾸면 문자열 타입이 출력된다.

또한 앞부분에 이진수임을 표시한 ‘0b’라는 문자가 같이 붙어서 출력된다.

예를 들어 ‘ bin(arr1[i] | arr2[i]) ‘를 입력하면,

'0b1111'이 출력되는 식이다.

앞에 ‘0b’를 제거하기 위해 슬라이싱( [2:])을 사용했다.

그리고 작은 숫자의 경우 OR연산 결과 5자리가 모두 채워지지 않을 수 있다.(ex. 1001(2))

따라서 지정된 자리수를 채우지 못할 경우 앞에 0을 넣어주는 zfill() 함수를 사용하여 자릿수를 맞춰준다.

 

2) 문자열 변환 및 정답 출력

 

answer = []

for i in range(len(arr1):
    bin_or = bin(arr[i] | arr[i])[2:].zfill(len(arr1))

    answer.append(bin_or.replace('0', ' ').replace('1', '#')

 

replace(’바꾸기 전’, ‘바꾼 후’) 함수를 활용하여 ‘0’을 공백(’ ‘)으로 ‘1’을 ‘#’으로 바꿔준다.

그런 다음 정답 리스트에 추가를 해주면 최종 답이 완성된다.

전체 코드는 아래와 같다.

 

3) 전체 코드

 

def solution(n, arr1, arr2):
    answer = []

    for i in range(len(arr1)):
        or_bin = bin(arr1[i] | arr2[i])[2:].zfill(len(arr1))
        answer.append(or_bin.replace('0', ' ').replace('1', '#'))

    return answer

+ Recent posts