Python/프로그래머스

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

묘걍 2023. 8. 30. 19:13

문제

비밀지도

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

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

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

입력 형식

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

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

출력 형식

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

 

내가 생각한 풀이 방법

10진수를 2진수로

잘 모름,, 아무리 생각해도 모르겠음 이 부분만 힌트 얻어보기

찾아보니 bin()함수로 간단히 끝낼 수 있을 것 같아서 이 부분에서 행렬까지 만들기

2진수로 나온 결과 각각을 배열로 하고, 그것들을 다시 빈 배열에 append해서 하나의 행렬로 만들기

arr1과 arr2 각각에 대한 행렬이 따로 나올 것

 

벽과 공백 구분하기

이중 for문 활용

첫 번째 for문은 행렬 내의 하나의 배열에 접근

두 번째 for문은 배열 내의 각각의 요소에 접근하여 만약 해당 요소가 0일 경우 '  ', 1일 경우 '#'으로 바꿔줌

arr1과 arr2 각각에 대한 행렬이 따로 나올 것

 

전체 지도 만들기

arr1과 arr2의 같은 자리 요소([i][j])에 접근하여 arr1[i][j]과 arr2[i][j] 모두 '  '라면 그 곳은 '  '

이외의 경우는 모두 '#'

예전에 풀었던 행렬 문제와 마찬가지로

for i in ~: 에서는 새로운 배열을 만들어주고

for j in ~: 에서 그 배열을 채운 채로 빈 행렬에 append 해주는 식으로 진행

 

함수를 따로 만들지 solution 내에서 다 해결할지도 고민

이진수로 만드는 것과 벽과 공백 구분하는 걸 함수로 따로 만들고

solution 내에서 해당 함수를 호출한 뒤 전체 지도를 만드는 방식으로 해보고 싶은데 잘 될지 모르겠다

 

코드로 구현

1차 시도

def to_bin(arr):
    bin_matrix = []
    for i in arr:
        n_to_bin = bin(i)[2:]
        bin_list = []
        for j in n_to_bin:
            bin_list.append(int(j))
        bin_matrix.append(bin_list)
    return bin_matrix

def wall_or_empty(arr):
    for i in range(len(arr)):
        for j in range(len(arr[i])):
            if arr[i][j] == 1:
                arr[i][j] = '#'
            else:
                j = ' '
    return arr

def solution(n, arr1, arr2):
    answer = []
    bin_mat_1 = to_bin(arr1)
    bin_mat_2 = to_bin(arr2)
    woe_1 = wall_or_empty(bin_mat_1)
    woe_2 = wall_or_empty(bin_mat_2)
    for i in range(n):
        temp = ''
        for j in range(n):
            if woe_1[i][j] == 0 and woe_1[i][j] == 0:
                temp.append(' ')
            else:
                temp.append('#')
        answer.append(temp)
        answer.append(', ')
    return answer

- bin()은 Ob라는 접두사가 붙으므로 [2:]를 통해 떼어준다

- bin()은 결과가 문자열이다

- 처음에는 인덱스가 아닌 요소 자체에 접근했는데 그러면 바로 변경이 불가해서 인덱스로 접근하고 해당 인덱스의 요소의 값을 바꿔주는 방식으로 진행

- 보니까 결과값이 [[]]의 행렬 형태가 아니라 배열 내에 문자열을 콤마(,)로 구분한 형태라서 일단 temp를 문자열로 초기화하고 진행해봄. 구분하기 위해 temp를 append 한 뒤에 ,와 공백을 붙여봄

 

2차 시도

def to_bin(arr):
    bin_matrix = []
    for i in arr:
        n_to_bin = bin(i)[2:]
        bin_list = []
        for j in n_to_bin:
            bin_list.append(int(j))
        bin_matrix.append(bin_list)
    return bin_matrix

def wall_or_empty(arr):
    for i in range(len(arr)):
        for j in range(len(arr[i])):
            if arr[i][j] == 1:
                arr[i][j] = '#'
            else:
                arr[i][j] = ' '
    return arr

def solution(n, arr1, arr2):
    answer = []
    bin_mat_1 = to_bin(arr1)
    bin_mat_2 = to_bin(arr2)
    woe_1 = wall_or_empty(bin_mat_1)
    woe_2 = wall_or_empty(bin_mat_2)
    for i in range(n):
        temp = ''
        for j in range(n):
            if woe_1[i][j] == 0 and woe_1[i][j] == 0:
                temp += ' '
            else:
                temp += '#'
        answer.append(temp)
        answer.append(', ')
    return answer

- 문자열에는 append가 아니라 += 을 써야한다!!!! (결과값 예시 보고 급하게 문자열로 바꾸다가 놓침)

- 인덱스로 접근한다 해놓고 안 고친 부분이 있었음..

 

3차 시도

def to_bin(arr, n):
    bin_matrix = []
    for i in arr:
        n_to_bin = bin(i)[2:].zfill(n)
        bin_list = []
        for j in n_to_bin:
            bin_list.append(int(j))
        bin_matrix.append(bin_list)
    return bin_matrix

def wall_or_empty(arr):
    for i in range(len(arr)):
        for j in range(len(arr[i])):
            if arr[i][j] == 1:
                arr[i][j] = '#'
            else:
                arr[i][j] = ' '
    return arr

def solution(n, arr1, arr2):
    answer = []
    bin_mat_1 = to_bin(arr1, n)
    bin_mat_2 = to_bin(arr2, n)
    woe_1 = wall_or_empty(bin_mat_1)
    woe_2 = wall_or_empty(bin_mat_2)
    for i in range(n):
        temp = ''
        for j in range(n):
            if woe_1[i][j] == 0 and woe_2[i][j] == 0:
                temp += ' '
            else:
                temp += '#'
        answer.append(temp)
    return answer

- zfill(n)은 문자열의 길이가 n이 될 때 까지 문자열의 앞에 0을 붙여준다.

- 사소한 오류들 고침

- 굳이 ', ' 붙일 필요 없는 듯?

 

4차 시도

def to_bin(arr, n):
    bin_matrix = []
    for i in arr:
        n_to_bin = bin(i)[2:].zfill(n)
        bin_list = []
        for j in n_to_bin:
            bin_list.append(int(j))
        bin_matrix.append(bin_list)
    return bin_matrix

def wall_or_empty(arr):
    for i in range(len(arr)):
        for j in range(len(arr[i])):
            if arr[i][j] == 1:
                arr[i][j] = '#'
            else:
                arr[i][j] = ' '
    return arr

def solution(n, arr1, arr2):
    answer = []
    bin_mat_1 = to_bin(arr1, n)
    bin_mat_2 = to_bin(arr2, n)
    woe_1 = wall_or_empty(bin_mat_1)
    woe_2 = wall_or_empty(bin_mat_2)
    for i in range(n):
        temp = ''
        for j in range(n):
            if woe_1[i][j] == ' ' and woe_2[i][j] == ' ':
                temp += ' '
            else:
                temp += '#'
        answer.append(temp)
    return answer

- 이미 wall_or_empty에서 벽과 공백으로 바꿔놓고 전체 지도 만들 때 0인지 아닌지를 검사하고 있었다

 

조금더 간결한 코드로 만들어보기도 해야겠다.

코드 짜면서 생각한 부분은 어차피 결과를 문자열로 내야하는데 굳이 위에서 리스트로 변환할 필요가 있을까에 대해 고민해봐야겠다.

다른 사람 풀이

def solution(n, arr1, arr2):
    answer = []
    arr1_bin = []
    arr2_bin = []
    for i in range(n):
        arr1_bin.append(bin(arr1[i])[2:])
        arr2_bin.append(bin(arr2[i])[2:])
        arr1_bin[i] = ('0' * (n-len(arr1_bin[i]))) + arr1_bin[i]
        arr2_bin[i] = ('0' * (n-len(arr2_bin[i]))) + arr2_bin[i]
    
        tmp = ''
        for p in range(n):
            if arr1_bin[i][p] == '1' or arr2_bin[i][p] == '1':
                tmp += '#'
            elif arr1_bin[i][p] == '0' and arr2_bin[i][p] == '0':
                tmp += ' '
        answer.append(tmp)
        
    return answer

https://velog.io/@godiva7319/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Level1-1%EC%B0%A8-%EB%B9%84%EB%B0%80%EC%A7%80%EB%8F%84-Python

 

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

프로그래머스 Level1 [1차] 비밀지도 Python 풀이

velog.io

def solution(n, arr1, arr2):
    answer = []
    for i in range(n):
        arr1[i] = format(arr1[i], 'b').zfill(n)
        arr2[i] = format(arr2[i], 'b').zfill(n)
        
        temp = ''
        for a, b in zip(arr1[i], arr2[i]):
            if a == '0' and b == '0':
                temp += ' '
            if a == '1' or b == '1':
                temp += '#'
        answer.append(temp)
        
    return answer

https://dduniverse.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-2018-KAKAO-BLIND-RECRUITMENT-%EB%B9%84%EB%B0%80%EC%A7%80%EB%8F%84-%ED%8C%8C%EC%9D%B4%EC%8D%AC-python

 

프로그래머스 | 2018 KAKAO BLIND RECRUITMENT | 비밀지도 [파이썬 python]

코딩테스트 연습 - [1차] 비밀지도 비밀지도 네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기

dduniverse.tistory.com