[프로그래머스/파이썬] 자물쇠와 열쇠(60059) 풀이

업데이트:



문제 정보


풀이

문제

열쇠 행렬을 회전/이동시켜 자물쇠의 모든 홈(0)을 정확히 메울 수 있는지 판별하는 문제입니다.

코드

def solution(key, lock):
    hole = 0
    for row in lock: hole += row.count(0)
    if hole == 0: return True

    for i in range(4):
##        print('======')
##        for row in key: print(*row)
##        print('======')
        for rStep in range(len(key)+len(lock)-1):
            for cStep in range(len(key)+len(lock)-1):
                if isMatched(key, lock, rStep, cStep, hole): return True
        key = rotateMatrixCW(key)
        
    return False

def isMatched(key, lock, rStep, cStep, hole):
    rStart = max(len(key) - rStep - 1, 0)
    rEnd = min(len(key), len(lock) + len(key) - rStep - 1)
    rLockStart = max(0, rStep - len(key) + 1)
    
    cStart = max(len(key) - cStep - 1, 0)
    cEnd = min(len(key), len(lock) + len(key) - cStep - 1)
    cLockStart = max(0, cStep - len(key) + 1)

##    print(f'rStep:{rStep}, rStart: {rStart}, rEnd: {rEnd}, rlockStart: {rLockStart}, cStep:{cStep}, cStart: {cStart}, cEnd: {cEnd}, clockStart: {cLockStart}, hole: {hole}')

    matched = True
    cnt = 0
    for i in range(rStart, rEnd):
        for j in range(cStart, cEnd):
##            print(f'key: ({i}, {j}, lock:({rLockStart+i-rStart}, {cLockStart+j-cStart}))')
            matched &= key[i][j] !=\
                       lock[rLockStart+i-rStart][cLockStart+j-cStart]
            if key[i][j] == 1 and\
               lock[rLockStart+i-rStart][cLockStart+j-cStart] == 0: cnt += 1
                
##    print(matched, cnt)
    return matched and cnt == hole

def rotateMatrixCW(mat):
    result = []
    for i in range(len(mat)):
        row = []
        for j in range(len(mat)-1, -1, -1):
            row.append(mat[j][i])
        result.append(row)
    return result

#print(solution([[0, 0, 0], [1, 0, 0], [0, 1, 1]],[[1, 1, 1], [1, 1, 0], [1, 0, 1]]))
##print(solution([[0, 0, 0, 0], [1, 0, 0, 0], [0, 1, 0, 0], [1, 0, 0,1]], [[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 0], [1, 1, 1, 0, 1]]))

설명

열쇠를 4번 회전시키며, 가능한 모든 이동 위치에 대해 자물쇠와 겹치는 영역만 비교합니다.

검증 조건은 두 가지입니다.

  • 겹치는 모든 칸에서 값이 서로 달라야 함(돌기-홈)
  • 자물쇠의 홈 개수와 정확히 같은 수의 홈이 메워져야 함

하나라도 만족하면 True, 끝까지 없으면 False를 반환합니다.



댓글남기기