[Python] 프로그래머스 - [1차] 비밀 지도

2 minute read

프로그래머스 - [1차] 비밀 지도


링크: https://programmers.co.kr/learn/courses/30/lessons/17681

문제 설명


네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.

  1. 지도는 한 변의 길이가 n인 정사각형 배열 형태로, 각 칸은 “공백”(“ “) 또는 “벽”(“#”) 두 종류로 이루어져 있다.
  2. 전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 “지도 1”과 “지도 2”라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.
  3. “지도 1”과 “지도 2”는 각각 정수 배열로 암호화되어 있다.
  4. 암호화된 배열은 지도의 각 가로줄에서 벽 부분을 1, 공백 부분을 0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.

secret map

네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.

입력 형식


입력으로 지도의 한 변 크기 n 과 2개의 정수 배열 arr1, arr2가 들어온다.

  • 1 ≦ n ≦ 16
  • arr1, arr2는 길이 n인 정수 배열로 주어진다.
  • 정수 배열의 각 원소 x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2n - 1을 만족한다.

출력 형식


원래의 비밀지도를 해독하여 '#', 공백으로 구성된 문자열 배열로 출력하라.

입출력 예제


  • 매개변수
    n 5
    arr1 [9, 20, 28, 18, 11]
    arr2 [30, 1, 21, 17, 28]
    출력 ["#####","# # #", "### #", "# ##", "#####"]
  • 매개변수
    n 6
    arr1 [46, 33, 33 ,22, 31, 50]
    arr2 [27 ,56, 19, 14, 14, 10]
    출력 ["######", "### #", "## ##", " #### ", " #####", "### # "]

코드


def solution(n, arr1, arr2):
    answer = []
    a1 = []
    a2 = []
    for i in range(n):
        a1.append(format(arr1[i], 'b'))
        a2.append(format(arr2[i], 'b'))
        a1[i] = ('0' * (n-len(a1[i]))) + a1[i]
        a2[i] = ('0' * (n-len(a2[i]))) + a2[i]
        
        tmp = ''
        for p in range(n):
            if a1[i][p] == '1' or a2[i][p] == '1':
                tmp += '#'
            elif a1[i][p] == '0' and a2[i][p] == '0':
                tmp += ' '
        answer.append(tmp)
        
    return answer
다른 사람 코드
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

코드 설명


  • 내 코드

    • a1.append(format(arr1[i], 'b'))
      a2.append(format(arr2[i], 'b'))
      a1[i] = ('0' * (n-len(a1[i]))) + a1[i]
      a2[i] = ('0' * (n-len(a2[i]))) + a2[i]
      

      format(arr1[i], ‘b’) 를 이용해 10진수 값을 2진수로 바꿔줍니다.

      3,4번째 줄은 자릿수에 맞춰 0을 채워주는 코드 입니다.

    • tmp = ''
      for p in range(n):
          if a1[i][p] == '1' or a2[i][p] == '1':
          tmp += '#'
          elif a1[i][p] == '0' and a2[i][p] == '0':
          tmp += ' '
      answer.append(tmp)
      

      a1[i][p] 가 1이거나 a2[i][p] 가 1 이면 벽 부분 이므로 # 으로 채워줍니다.

      ​ ex) a1[0] = 01001 (예제 1의 첫 번째 줄) / a2[0] = 11110

      ​ a1[i][p] => a1[0][0] = 0 / a2[i][p] => a2[0][0] = 1

      둘 다 0이면 공백 부분이므로 “ “ 으로 채워줍니다.

  • 다른 사람코드

    • for i,j in zip(arr1,arr2):
      	a12 = str(bin(i|j)[2:])
      	a12=a12.rjust(n,'0')
      

      zip(arr1, arr2) => (arr1[0], arr2[0]) , (arr1[1], arr2[1]) , … 반복

      bin(number) => number를 이진수 문자열로 바꾸는 함수

      ​ - i j => bit 단위로 i와 j를 or연산 합니다.
      - [2:] 를 하는 이유는 bin() 함수를 사용하면 '0b(2진수변환숫자)' 가 되므로 0b를 제거해주기 위해 슬라이싱 사용
      

      rjust()는 문자열을 오른쪽 정렬해서 보기 좋게 출력할 때 사용하는 함수

      ​ - rjust(전체자리 숫자, 공백이 있을 경우 채울 텍스트) => a12.rjust(n, ‘0’)

    • a12=a12.replace('1','#')
      a12=a12.replace('0',' ')
      

      a12가 1이면 #으로 바꾸고 0 이면 공백으로 바꿉니다.

Leave a comment