Lv2. [2021 Dev-Matching 웹 백엔드 개발자(상반기)] 행렬 테두리 회전하기

행렬 테두리 회전하기

프로그래머스 문제

문제 설명

아래는 6 x 6 크기의 행렬이다.

행렬테두리회전하기-1.png

이때 (2, 2) 에서 (5, 4) 까지의 영역을 시계방향으로 회전시킨 그림이다.

행렬테두리회전하기-2.png

파란 영역을 시계 방향으로 회전시키면 아래와 같이 된다.

행렬테두리회전하기-3.png

해당 영역에 해당하는 숫자 중에서 가장 작은 숫자들을 반환하면 된다.

해결 과정

우선 회전해야하는 영역만 추출해보자.

행렬테두리회전하기-4.png

해당 영역에서 회전을 한 결과이다.

행렬테두리회전하기-5.png

이것을 flat 하게 보면 아래와 같다.

행렬테두리회전하기-6.png

여기서 마지막 숫자를 첫번째로 옮길 때 마지막 index 유무를 체크해서 로직을 작성해도 되지만 그냥 첫 element 를 마지막으로 옮기는 방식으로 구현할 수 있다.

행렬테두리회전하기-7.png

윗면부터 시계방향으로 각 면에 1, 2, 3, 4 를 부여해서 보면 1 과 3 은 x 축 대칭이고 2 와 4 는 y 축 대칭이다. 그렇기에 1, 2 면만 구하면 나머지 면은 대칭으로 구할 수 있다.

행렬테두리회전하기-8.png

전체 코드

def solution(rows, columns, queries):
    answer = []

    maps = [((row * columns + col) + 1) for row in range(rows) for col in range(columns)]

    for query in queries:
        y1, x1, y2, x2 = map(lambda x: x - 1, query)

        border1 = [(y1, x) for x in range(x1, x2 + 1)]
        border2 = [(y, x2) for y in range(y1, y2 + 1)][1:-1]
        border3 = list(map(lambda yx: (y2, yx[1]), border1))
        border4 = list(map(lambda yx: (yx[0], x1), border2))

        border3.reverse()
        border4.reverse()

        borders = border1 + border2 + border3 + border4 + [border1[0]]
        values = list(map(lambda yx: maps[yx[0] * columns + yx[1]], borders))

        for i in range(1, len(borders)):
            y, x = borders[i]
            maps[y * columns + x] = values[i - 1]

        answer.append(sorted(values)[0])

    return answer


print(solution(6, 5, [[1, 1, 6, 5]]))
print(solution(6, 6, [[2, 2, 5, 4], [3, 3, 6, 6], [5, 1, 6, 3]]), [8, 10, 25])
print(solution(100, 97, [[1, 1, 100, 97]]), [1])
print(solution(3, 3, [[1, 1, 2, 2], [1, 2, 2, 3], [2, 1, 3, 2], [2, 2, 3, 3]]), [1, 1, 5, 3])

행렬테두리회전하기-9.png


Lv2. [2021 KAKAO BLIND RECRUITMENT] 순위 검색

순위 검색

엘카데미 AWS Certified Solutions Architect - Associate (SAA-C03) 중간 점검

중간 점검

엘카데미 에서 신년 환급 이벤트가...

NCloud LB & SourcePipeline 구축하기
tech collection 서비스 성능 개선하기
Selenium 복권 구매 자동화 만들어보기
디자인 패턴
책 리뷰
블로그 챌린지