본문 바로가기

프로그래머스 퀴즈(Python)/level 3

23.05.13 파이썬 코딩 퀴즈#242 표 병합 (프로그래머스 스쿨)

이번 문제는 표 병합 문제이다.

설명이 굉장히 길고 자세하기 때문에 잘 읽어볼 필요가 있지만, 엑셀을 어느정도 아는 사람이라면 명령어만 보고도 내용을 이해할 수 있다.

먼저 'UPDATE' 명령어 이다.

좌표가 주어지는 경우 해당 좌표의 값을 value 로 바꾸어 주어야 한다.

value 만 두 개 주어지는 경우라면, value1의 값을 가진 모든 셀의 값을 value2로 바꾸어 주어야 한다.

다음 명령어는 'MERGE' 이다.

두 전달받은 (r1,c1) 와 (r2,c2) 을 합치는 역할이다. 이 때 인접하지 않은 경우라면 그 사이에 존재하는 셀들은 영향을 받지 않는다! 범위 선택이 아닌, 단순 두 셀의 내용을 합치는데 의미가 있다.

만약 (r1,c1)의 셀 값이 없다면, 합쳐진 값은 (r2,c2)의 값을 가지지만, (r1,c1)값이 존재할 경우 (r2,c2)값에 상관없이 두 셀은 (r1,c1)값을 가지게 된다.

다음 명령어는 'UNMERGE' 이며, 해당 셀의 모든 병합을 해제한다.

만약 해제하기 전 셀이 값을 가지고 있다면 그 값은 (r,c) 위칑 셀이 가지게 된다.

'PRINT' 명령어는 해당 (r,c)의 셀 값을 출력하며, 비어있는 경우 'EMPTY'를 출력한다.

 

이제 예시를 보면서 내용을 다시 살펴보자.

전달받은 명령어를 순서대로 수행하면 위와 같은 표가 그려진다.

그 다음 'MERGE' 명령어를 받아 수행하면, 위 그림과 같은 표가 그려진다.

이때 병합된 셀 어디를 선택하더라도 같은 값 'category'를 가지게 된다.

다음 다시 UPDATE 명령어를 전달해 특정 value1을 모두 value2로 바꾸었고, 병합된 셀의 값도 group 으로 바꾼 모습이다.

그리고 가장 주의깊게 봐야할 UNMERGE 이다

(1,4)에 커서를 놓고 병합을 해제 하였기 때문에, 기존의 값 'group' 은 (1,4) 셀만 가지게 되고, 나머지 셀은 빈 값을 가지게 된다.

그리고 해당 문제는 'PRINT' 명령어가 실행된 결과를 순서대로 문자열 배열에 담아 return 해 주어야 한다.

특별한 제한 사항은 없다.

다시 입출력 예 2번을 살펴보자.

모든 UPDATE를 실행하면 위와 같은 표를 가지게 된다.

'MERGE 2 1 1 1' 실행 후 'PRINT 1 1' 실행 값은 'd' 가 된다.

그리고 'UNMERGE 2 2' 실행 후 병합된 값은 (2,2)에만 남게 되므로, 마지막 'PRINT 1 1' 실행 값은 'EMPTY'가 된다.

 

'MERGE'와 'UNMERGE'로 인해 문제 난이도가 높은 것 처럼 보였다.

처음으로 작성한 코드는 아니다.... 처음 작성한 코드는 set()을 이용한 dict 였는데, 생각해보면 너무 어렵게만 생각할 것 같다.

 

먼저 병합 정보를 담을 merged 와 각 셀 값을 기록한 cells를 생성해 주었다.

그 다음 주어진 commands를 반복하며 해당 명령어를 수행해 주면 된다.

1. UPDATE

UPDATE는 그 길이에 따라 2가지로 분류된다. 먼저 셀값을 입력하는 경우를 보면

현재 전달받은 좌표 (r,c)를 기준으로 해당 좌표를 바로 사용하지 않고, 해당 셀과 연결된 셀 좌표를 가져온다.

그리고 연결된 셀 값을 바꾸어 주면 된다.

value1을 value2로 치환하는것은, 전체를 탐색하여 조건문을 통해 값을 변경해 주었다.

2. MERGE

처음에는 set()을 이용하여 각 좌표쌍을 값으로 가지는 모든 키 들을 생성하려 하였지만, 생각보다 단순하게 구현 가능하다.

먼저 대상좌표 r1,c1,r2,c2를 각 셀과 연결된 좌표 x1,y1,x2,y2로 치환해 주고, 해당 (x1,y1)의 셀 값이 'EMPTY'인 경우만 cells[x2][y2]로 바꾸어 주면 된다.

그렇게 하는 이유는 merged 의 연결정보를 먼저 전달된 x1,y1 값을 기준으로 정렬해 주기 때문이다. 그리고 이때 정렬해줄 값은 merged의 연결정보가 x2,y2 인 값만 x1,y1으로 갱신해 주면 된다.

3. UNMERGE

병합 해제는 생각보다 단순하다. 먼저 값이 변하지 않아야 하는 기준값을 따로 변수로 저장한 뒤,

해당 (x,y) ((r,c)와 병합된 최상위 셀 좌표) 와 병합 정보를 가지고 있는 모든 merged 좌표를 자기 자신으로 설정해주고, cells 의 셀 값은 다시 'EMPTY'로 바꾸어 준다.

그리고 cells[r][c] 값만 원래 값으로 돌려놓으면 된다.

 

4. PRINT 

PRINT 명령어는 cells 값을 answer에 넣어주어야 하지만, 실제 그 기준은 현재 (r,c)에 연결된 (x,y)가 기준이다.

예를 들어 위와 같은 총 3개의 명령어를 전달받아 수행한다고 가정하면,

첫번째 UPDATE 명령에 의해 (0,1)에 MENU 가 채워진다.

그 다음 MERGE 명령에 의해 (0,1) 과 (0,3)의 merged 값이 바뀌게 되는데, 이때 CELLS[0][1] 에는 이미 값이 존재하기 때문에 조건문은 작동하지 않는다. 그리고 MERGED[0][3] 의 값만 (0,1)로 바뀌게 된다.

마지막 PRINT 명령어의 경우 MERGED[0][3] 의 값 (0,1)을 받아 실제로는 CELLS[0][1]의 값을 ANSWER에 전달하게 된다.

 

거의 3시간을 넘게 set() 과 dict 를 이용해 만들어 보려고 애를 썼는데, 더이상의 반례를 찾지 못해 결국 구글링을 통해 도움을 얻었다.

 

생각 보다 구현 자체는 단순한 문제인데, 그 과정을 그리고 생각하는게 어려웠던 문제 였다.