(Python) [2020카카오공채] 자물쇠와 열쇠
알고리즘/[Python] 프로그래머스

(Python) [2020카카오공채] 자물쇠와 열쇠

출처 : https://programmers.co.kr/learn/courses/30/lessons/60059?language=python3

 

코딩테스트 연습 - 자물쇠와 열쇠 | 프로그래머스

[[0, 0, 0], [1, 0, 0], [0, 1, 1]] [[1, 1, 1], [1, 1, 0], [1, 0, 1]] true

programmers.co.kr


Hint.

 

1. 2차원 배열로 이루어진 열쇠를 시계방향으로 90도 회전하려면?

 

 

 

2. 자물쇠와 padding


 

(Python) [2020카카오공채] 자물쇠와 열쇠

[2020 카카오 공채 문제] 자물쇠와 열쇠


In [1]:
import copy
In [2]:
# key를 90도 회전시키기
def rotate(key):
    rotate_key = copy.deepcopy(key)
    
    y = len(key) - 1
    for i in range(len(key)):
        x = 0
        for j in range(len(key)):
            rotate_key[x][y]= key[i][j]
            x = x + 1
        y = y-1
    return rotate_key
In [3]:
# 자물쇠 숫자 2로 padding하기
def padding(key, lock):
    len_key = len(key)
    len_lock = len(lock)
    
    #왼쪽 오른쪽 padding
    for i in range(len_lock):
        lock[i] = [2]*(len_key-1) + lock[i] + [2]*(len_key-1)
    # 윗부분 padding
    for _ in range(len_key-1):
        lock.insert(0, [2]*((len_key-1)*2 + len_lock))
    # 아래부분 padding
    for _ in range(len_key-1):
        lock.append([2]*((len_key-1)*2 + len_lock))
    # lock을 padding시켜주는 것이 목적이므로, return값이 없어도 무관하다.
    
In [4]:
def solution(a, b):
    # 열쇠
    key = a
    key_90 = rotate(key)
    key_180 = rotate(key_90)
    key_270 = rotate(key_180)

    # 자물쇠
    lock = b

    # 자물쇠 '0'의 갯수
    lock_0 = 0
    for i in range(len(lock)):
        lock_0 = lock_0 + lock[i].count(0)

    padding(key, lock)
    answer = False
    for x_start in range(len(lock)-len(key)+1):
        for y_start in range(len(lock)-len(key)+1):
            # 해당 위치에 자물쇠의 0이 모두 존재하는가?
            cnt = 0
            for i in range(len(key)):
                for j in range(len(key)):
                    if lock[x_start+i][y_start+j] == 0:
                        cnt = cnt + 1
            if cnt == lock_0: # lock_0 = 자물쇠의 총 0의 갯수
                for fit_key in [key, key_90, key_180, key_270]:
                    new_lock_0 = lock_0
                    key1_and_lock1 = 0
                    for i in range(len(key)):
                        for j in range(len(key)):
                            # 열쇠의 1과 자물소의 1이 만난다 = i,j for문을 빠져나가라
                            # 열쇠의 1과 자물쇠의 0이 만난다 = new_lock_0을 1씩 감소시켜라
                            # 그 외에는 아무일도 일어나지 않는다
                            if fit_key[i][j]==1 and lock[x_start+i][y_start+j]==1:
                                key1_and_lock1 = 1
                                break
                            elif fit_key[i][j]==1 and lock[x_start+i][y_start+j]==0:
                                new_lock_0 = new_lock_0 - 1
                        if key1_and_lock1==1:
                            break
                    # 열쇠가 맞아 떨어진다.
                    if new_lock_0 == 0:
                        answer = True
                        return answer     
            else:
                continue
    return answer
In [5]:
# key = [[0, 0, 0], [1, 0, 0], [0, 1, 1]]
# lock = [[1, 1, 1], [1, 1, 0], [1, 0, 1]]
# solution(key, lock)

solution([[0, 0, 0], [1, 0, 0], [0, 1, 1]], [[1, 1, 1], [1, 1, 0], [1, 0, 1]])
Out[5]:
True