[코테 스터디] 구현, 기둥과 보 설치

Q12. 기둥과 보 설치

🐣문제

죠르디는 기둥과 보를 이용하여 벽면 구조물을 자동으로 세우는 로봇을 시뮬레이션 할 프로그램을 만들고자 합니다.
프로그램은 2차원 가상 벽면에 기둥과 보를 이용한 구조물을 설치할 수 있는데, 기둥과 보는 길이가 1인 선분으로 표현되며 다음과 같은 규칙을 가지고 있습니다.

  • 기둥은 바닥 위에 있거나 보의 한쪽 끝 부분 위에 있거나, 또는 다른 기둥 위에 있어야 합니다.
  • 보는 한쪽 끝 부분이 기둥 위에 있거나, 또는 양쪽 끝 부분이 다른 보와 동시에 연결되어 있어야 합니다.
  • 단, 바닥은 벽면의 맨 아래 지면을 말합니다.
  • 2차원 벽면은 n x n 크기 정사각 격자 형태이며, 각 격자는 1 x 1 크기입니다.
  • 맨 처음 벽면은 비어있는 상태입니다.
  • 기둥과 보는 격자선의 교차점에 걸치지 않고, 격자 칸의 각 변에 정확히 일치하도록 설치할 수 있습니다.


    벽면의 크기 n, 기둥과 보를 설치하거나 삭제하는 작업이 순서대로 담긴 2차원 배열 build_frame이 매개변수로 주어질 때, 모든 명령어를 수행한 후 구조물의 상태를 return 하도록 solution 함수를 완성해주세요.


    프로그래머스 링크 | https://programmers.co.kr/learn/courses/30/lessons/60061

🐥풀이

작업할 구조물을 리스트에 저장하여 최종 리스트를 조건대로 정렬하여 출력하면 된다. 기둥과 보를 설치하거나 삭제하는 작업을 하나씩 꺼내서 판단하여 append 또는 pop 한다.


구조물을 작업할 수 있는 지 판단하는 별도의 함수를 정의한다.
: 기둥이면, 기둥 작업이 성립되는 조건을 모두 만족하지 않으면 False, 하나라도 만족하면 True를 반환한다. 보이면, 보 작업이 성립되는 조건을 모두 만족하지 않으면 False, 하나라도 만족하면 True를 반환한다.


build_frame에서 구조물 작업 정보를 하나씩 꺼내서 작업 가능성을 하나씩 판단하고 작업 정보 리스트를 업데이트 한다.
: 설치이면, 정보를 append하고 작업 가능성을 체크한다. 작업할 수 없으면 pop하여 다시 뺀다. 반대로 삭제이면, 정보를 pop하고 작업 가능성을 체크한다. 작업할 수 없으면 append하여 다시 추가한다.

🐓코드

def checking(result):
    for build in result:
        x, y, a = build # 가로, 세로, 구조물
        # 기둥
        if a==0:
            # 바닥 위에 있지 않고, 보의 한쪽 끝 부분 위에 있지도 않고, 다른 기둥 위에도 없을 때
            if y!=0 and [x-1, y, 1] not in result and [x,y,1] not in result and [x,y-1, 0] not in result:
                return False
        # 보
        elif a==1:
            # 어느 한 쪽 끝 부분도 기둥 위에 있지 않고, 양쪽 끝 부분이 다른 보와 연결되어 있지도 않을 때
            if [x,y-1,0] not in result and [x+1,y-1,0] not in result and not ([x-1,y,1] in result and [x+1,y,1] in result):
                return False
    
    return True
                

def solution(n, build_frame):
    result = [] # 설치할 구조물
    
    for frame in build_frame:
        # x, y : 기둥과 보의 교차점 좌표 [가로 좌표, 세로 좌표] 
        # a : 구조물의 종류 (0은 기둥, 1은 보)
        # b : 설치 or 삭제 (0은 삭제, 1은 설치)
        x, y, a, b = frame
        
        # 설치
        if b==1:
            result.append([x,y,a])
            # 설치할 수 없으면 다시 삭제
            if not checking(result):
                result.pop()
        # 삭제
        elif [x,y,a] in result:
            result.pop(result.index([x,y,a]))
            # 삭제할 수 없으면 다시 추가
            if not checking(result):
                result.append([x,y,a])
                
    # 1. x좌표 기준으로 오름차순
    # 2. x좌표가 같을 경우 y좌표 기준으로 오름차순
    # 3. x,y좌표가 모두 같은 경우 기둥이 보보다 앞에 오도록. (기둥은 0, 보는 1이므로 오름차순)
    return sorted(result, key=lambda x:(x[0],x[1],x[2]))

⭐2022.04.06

스터디 하는 시기에 풀 때는 리스트를 사용할 생각을 못하고 엄청 헤맸었다. 파이썬 리스트 만세~~

좋은 웹페이지 즐겨찾기