프로그래머스_기둥과 보 설치

임정민·2024년 1월 16일
0

알고리즘 문제풀이

목록 보기
144/173
post-thumbnail

프로그래머스 2020 KAKAO BLIND RECRUITMENT 구현 문제입니다. 실전에 대비하기 위해 60분 시간제한을 두고 풀었습니다.

문제

https://school.programmers.co.kr/learn/courses/30/lessons/60061

[나의 풀이]

⌛ 시간초과 (9.6/100점)


def solution(n, build_frame):
    answer = []
    
    wall = [[-1 for j in range(n+1)] for i in range(n+1)] # -1:빈공간,0:기둥,1:보 
    
    for frame in build_frame:
        x, y, beam, install = frame
        
        if install: # 설치
            now = wall[x][y]
            
            if not beam: # 기둥
                        
                check_l = wall[x-1][y]
                check_d = wall[x][y-1]
                
                if (y==0 and now==-1) or (check_d==0)or(check_l==1):
                    wall[x][y] = 0
                    print(x,y,"기둥 설치!")

            else: # 보
                check_d = wall[x][y-1]
                check_r_d = wall[x+1][y-1]
                check_l = wall[x-1][y]
                check_r = wall[x+1][y]
                
                if (now==0 or check_r==0) or (check_l==1 and check_r==1):
                    wall[x][y] = 1
                    print(x,y,"보 설치!")
                    
        else:
            now = wall[x][y]
            if not beam: # 기둥
                check_u = wall[x][y]
                check_u_l = wall[x-1][y+1]
                check_u_r = wall[x+1][y+1]
                
                if not (check_u==1 and check_u_l==1 and check_u_r==1):
                    wall[x][y] = -1
                    # print(x,y,"기둥 제거!")
                    
            else: # 보
                check_l = wall[x-1][y]
                check_r = wall[x+1][y]
                
                if not (now==1 and check_l==1 and check_r==1):
                    wall[x][y] = -1
                    # print(x,y,"보 제거!")
                    
                    
    # print(wall)
    
    for i in range(n+1):
        for j in range(n+1):
            v = wall[i][j]
            if v != -1:
                answer.append([i,j,v])
        
    answer.sort()
    # print(answer)
    return answer

주어지 n차원 평면과 [[x좌표,y좌표,기둥or보,설치or삭제], ...] 입력값이 주어지고 기둥과 보의 설치 및 삭제 규칙에 따라 완성되는 건축물을 반환하는 문제입니다.🐈🐈🐈

wall이라고 하는 2차원 평면을 -1로 모두 초기화하고

위 규칙에 따라서 조건을 정리한 뒤

# 기둥 설치
# 1) 바닥 위
# 2) 보의 한쪽 끝
# 3) 기둥 위

# 보 설치
# 1) 한쪽 끝이 기둥 위
# 2) 양쪽 끝이 다른 보

### 삭제

# 기둥&보
# 삭제 후에도 설치 규칙을 만족

이를 if-else문으로 구현하려하였으나 '삭제' 가능한 조건들을 모두 고려하는 것이 까다로워 시간을 초과하였고 이에 따라 다른 풀이를 참고하였습니다.

[다른 사람의 풀이1]


def solution(n, build_frame):
    def is_valid_structure(x, y, a, result):
        if a == 0: # 보
            if y == 0 or [x, y-1, 0] in result or [x, y, 1] in result or [x-1, y, 1] in result:
                return True
        else: # 기둥
            if [x, y-1, 0] in result or [x+1, y-1, 0] in result or ([x-1, y, 1] in result and [x+1, y, 1] in result):
                return True
        return False

    result = []
    for x, y, a, b in build_frame:
        if b == 1: # 건물 생성
            if is_valid_structure(x, y, a, result):
                result.append([x, y, a])
        else: # 건물 제거
            result.remove([x, y, a])
            for i in result:
                xpos, ypos, stru = i
                if not is_valid_structure(xpos, ypos, stru, result):
                    result.append([x, y, a])
                    break

    answer = sorted(result)
    return answer

'나의 풀이'와 같이 설치,삭제할 때마다 2차원 평면을 갱신하는 것이 아닌 is_valid_strcture()라는 하나의 함수로 규칙에 적합하지 판단하는 방식이였습니다.🕊️🕊️🕊️

건물을 생성할 때 기둥 or 보를 result에 추가한 뒤, 설치가 불가능한지 True or False를 반환하여 판단합니다.

또 삭제할 때는 기둥 or 보를 result에서 제거한 뒤, 삭제가 불가능할 때의 True or False 반환하는 방식입니다.

실제 2차원 평면을 만들어 갱신하지 않은점, 하나의 검증 함수로 설치,삭제를 모두 구현할 수 있다는 점이 포인트였습니다.

[다른 사람의 풀이2]


def check_build(answer):
    for x, y, a in answer:
        # 기둥인 경우
        if a == 0:
            # 좌표가 바닥에 해당 x
            # 좌표 아래에 기둥이 존재 x
            # 보의 한 쪽 위 x
            if (y != 0 and
                [x, y - 1, 0] not in answer and
                [x - 1, y, 1] not in answer and
                [x, y, 1] not in answer):
                return False
        # 보인 경우
        else:
            # 아래애 기둥 존재 x
            # 양쪽에 보 존재 x
            if ([x, y - 1, 0] not in answer and
                [x + 1, y - 1, 0] not in answer and
                ([x - 1, y, 1] not in answer or
                 [x + 1, y, 1] not in answer)):
                return False
    return True
 
def solution(n, build_frame):
    answer = []
    for x, y, a, b in build_frame:
        # 삭제라면
        if b == 0:
            answer.remove([x, y, a])
            # 삭제 후, check가 통과되지 못한다면, 재설치
            if not check_build(answer):
                answer.append([x, y, a])
        # 설치라면
        elif b == 1:
            answer.append([x, y , a])
            # 설치 후, check가 통과되지 못한다면, 삭제처리
            if not check_build(answer):
                answer.remove([x, y, a])
 
    answer.sort(key= lambda x : (x[0], x[1], x[2]))
    return answer

'다른 사람의 풀이1'과 같이 설치 및 삭제를 진행한 뒤, 이것이 가능한지 판단하는 함수로 판별하는 방식입니다.🐇🐇🐇

구현 문제같은 경우 자신있었지만 해당 문제의 경우 하드코딩으로 구현하기 까다로운 측면과 설치 및 삭제에 대해 하나의 판별 함수를 만들어 해결한 아이디어를 생각해내기 어려웠습니다.

다음에 다시 도전해보겠습니다. 감사합니다.

profile
https://github.com/min731

0개의 댓글