네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.
n
인 정사각형 배열 형태로, 각 칸은 "공백"(" ") 또는 "벽"("#") 두 종류로 이루어져 있다.1
, 공백 부분을 0
으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.
입력으로 지도의 한 변 크기 n
과 2개의 정수 배열 arr1
, arr2
가 들어온다.
n
<= 16arr1
, arr2
는 길이 n
인 정수 배열로 주어진다.x
를 이진수로 변환했을 때의 길이는 n
이하이다. 즉, 0 <= x
<= 2^n - 1을 만족한다.원래의 비밀지도를 해독하여 '#'
, 공백
으로 구성된 문자열 배열로 출력하라.
n | arr1 | arr2 | 출력 |
---|---|---|---|
5 | [9, 20, 28, 18, 11] | [30, 1, 21, 17, 28] | ["#####","# # #", "### #", "# ##", "#####"] |
6 | [46, 33, 33 ,22, 31, 50] | [27 ,56, 19, 14, 14, 10] | ["######", "### #", "## ##", " #### ", " #####", "### # "] |
def decode_map(n, num):
string = ''
for _ in range(n):
string += '#' if num % 2 else ' '
num = num // 2
return string[::-1]
def solution(n, arr1, arr2):
answer = []
for a1, a2 in zip(arr1, arr2):
final = a1 | a2
final = decode_map(n, final)
answer.append(final)
return answer
두 배열에서 같은 인덱스에 있는 요소끼리 OR 비트 연산을 한다면?
두 비밀지도 역할을 하는 arr1
, arr2
의 같은 인덱스에 있는 값들을 같이 가져와서 한 쪽이라도 벽인 부분은 벽으로 처리해야 한다. 벽은 1로 표기하고, 공백은 0으로 표현하므로 비트 OR 연산을 통해 둘을 합칠 수 있다.
합쳐진 하나의 자연수를 이진수로 고친다.
그렇게 두 개의 지도에서 OR 비트 연산을 하면 하나의 자연수가 나온다. 이 자연수를 이진수로 고쳤을 때 1인 부분은 벽, 0인 부분은 공백의 의미를 갖는다.
1일 때는 # 문자를, 0일 때는 공백 문자를
그러면 그 자연수를 계속해서 2로 나누면서 나머지의 값에 따라 문자를 달리해 이어붙이면 된다. 다만, 이 방식은 이진수에서 맨 뒷자리부터 구해지므로 마지막에 해당 문자열을 거꾸로 뒤집어야 한다.
def solution(n, arr1, arr2):
answer = []
for i,j in zip(arr1,arr2):
a12 = str(bin(i|j)[2:])
a12=a12.rjust(n,'0')
a12=a12.replace('1','#')
a12=a12.replace('0',' ')
answer.append(a12)
return answer
bin
내장 함수는 매개변수로 주어진 정수를 0b
가 붙은 이진 문자열로 변환한다. 예를 들어 3을 줬다면 0b11
이 반환되는 것이다. 그래서 해당 문자열의 2번째 인덱스부터 지도의 값이 된다.
다만 bin
내장 함수의 경우, 맨 앞의 0은 모두 생략하기 때문에 길이가 일정하지 않게 반환된다. 이 문제를 rjust
메서드를 활용해 해결한다. 길이가 n이 될 때까지 앞에 0 문자를 추가하는 방식으로 모든 이진 문자열의 길이를 통합한다.
이후에는 1은 # 문자로, 0은 공백 문자로 변환하면 지도의 해독이 완료된다.