기둥과 보 설치

boooookreeeed·2021년 11월 13일

코딩테스트

목록 보기
8/10

2020 kakao blind recruitment

문제 링크 :
https://programmers.co.kr/learn/courses/30/lessons/81303#


내가 생각한 문제 풀이

[시도1]
문제를 보고 그냥 단순하게 구현하는 것으로 충분할 것이라는 생각이 들었다.
조건이 좀 복잡하고 글이 길었지만 그냥 구현하면 될 거라고 생각했다.
삭제하는 케이스와 추가하는 케이스 보와 기둥 모두 나눠서 했는데
(알고리즘이랄 것이 없다) 오답이 나왔다.


시간 / 결과 / 패착

[시도1]
결과 : 19.2

패착 :
일단 삭제 가능 여부는 체크하지 않아도 된다.
삭제 해도 되는지 여부에서 이번 턴의 계획만 점검하니까 이전 것들이 연쇄적으로 확인되지 않아서 오답이 발생한 것 같다.
그러니까 정리하면, 애초에 모든 요소들을 다 점검했어야 하는 문제였고, 모든 요소들을 점검한다는 킥을 알았다면 삭제 함수를 따로 만들 필요 없이 삭제/추가 한 모든 요소가 가능한 것인가? 만 점검하면 된다.


문제 해설

build_frame의 길이가 1000이하로 매우 작으므로, 삭제 시에는 전수검사를 해야 한다.
라는 점을 딱 느꼈어야 했다.


코드

나의 오답 코드

# 7:40 -
# 매 번 조건에 맞는지 확인해서 건설 하거나 건설 하지 않음
# 테케는 다맞고 19.2
def checkbo(x, y, do, snowtown):
    if do == 0:  # 삭제
        if [x, y, 0] in snowtown or [x + 1, y, 0] in snowtown:  # 위에 기둥 있는 경우
            return False
        elif [x - 1, y, 1] in snowtown and [x + 1, y, 1] in snowtown:  # 앞뒤로 보가 있는 경우
            if [x - 1, y, 1] in snowtown and [x - 1, y - 1, 0] not in snowtown and [x, y - 1, 0] not in snowtown:
                return False
            elif [x + 1, y, 1] in snowtown and [x + 1, y - 1, 0] not in snowtown and [x + 2, y - 1, 0] not in snowtown:
                return False
        return True


    elif do == 1:  # 추가
        if [x, y - 1, 0] in snowtown or [x + 1, y - 1, 0]:
            return True
        elif [x - 1, y, 1] in snowtown and [x + 1, y, 1] in snowtown:
            return True
        return False


def checkgidung(x, y, do, snowtown):
    if do == 0:  # 삭제
        if [x, y + 1, 0] in snowtown:  # 다른 기둥이 내 위에 있는 경우
            return False
        elif [x, y + 1, 1] in snowtown:  # 내 위에 보가 있는 경우
            if [x + 1, y, 0] not in snowtown and not ([x - 1, y + 1, 1] in snowtown and [x + 1, y + 1, 1] in snowtown):
                return False
        elif [x - 1, y + 1, 1] in snowtown:  # 내 위에 보가 있는 경우
            if [x - 1, y, 0] not in snowtown and not ([x - 2, y + 1, 1] in snowtown and [x, y + 1, 1] in snowtown):
                return False
        return True

    elif do == 1:  # 추가
        if y == 0:
            return True
        elif [x, y - 1, 0] in snowtown:
            return True
        elif [x, y, 1] in snowtown or [x - 1, y, 1] in snowtown:
            return True
        return False


def solution(n, build_frame):
    answer = []

    for build in build_frame:
        x, y, a, b = build
        if a == 0:
            sol = checkgidung(x, y, b, answer)
            if sol and b == 0:  # True면 동시에 삭제면
                answer.remove([x, y, a])
            elif sol and b == 1:
                answer.append([x, y, a])
        elif a == 1:
            sol = checkbo(x, y, b, answer)
            if sol and b == 0:
                answer.remove([x, y, a])
            elif sol and b == 1:
                answer.append([x, y, a])

    # sort : 첫번째 두번째 세번째 어떻게 하는지 기록
    answer.sort()

    return answer

# [[0,0,0,1],[2,0,0,1],[4,0,0,1],[0,1,1,1],[1,1,1,1],[2,1,1,1],[3,1,1,1],[2,0,0,0],[1,1,1,0],[2,2,0,1]]

정답 코드

   def impossible(result):
    COL, ROW = 0, 1
    for x, y, a in result:
        if a == COL: # 기둥일 때
            if y != 0 and (x, y-1, COL) not in result and \
        (x-1, y, ROW) not in result and (x, y, ROW) not in result:
                return True
        else: # 보일 때
            if (x, y-1, COL) not in result and (x+1, y-1, COL) not in result and \
        not ((x-1, y, ROW) in result and (x+1, y, ROW) in result):
                return True
    return False

def solution(n, build_frame):
    result = set()
    
    for x, y, a, build in build_frame:
        item = (x, y, a)
        if build: # 추가일 때
            result.add(item)
            if impossible(result):
                result.remove(item)
        elif item in result: # 삭제할 때
            result.remove(item)
            if impossible(result):
                result.add(item)
    answer = map(list, result)
    
    return sorted(answer, key = lambda x : (x[0], x[1], x[2]))

추가 공부
sorted 함수와 sort 함수의 차이

문제 푸는 과정에서

 answer = map(list, result)
    return answer.sort(key = lambda x:(x[0], x[1], x[2]))

이 코드에 대해서
AttributeError: 'map' object has no attribute 'sort'
에러 발생. 확실하게 짚고 넘어가야 할 것 같다

python3에서 map은 list를 반환하지 않고 iterator를 반환한다.
sort는 list 객체의 속성이다
같은 맥락에서 str도 sort할 수 없고 sorted는 가능하다.
-> 속성 오류 발생

sorted함수를 사용하면 된다.
반복가능한 자료형 모두 가능하기 때문

sort()함수는 리스트 객체 그 자체를 정렬만 할 뿐 정렬된 결과를 반환하지 않는다.

a = [1,3,2,5,3]
a.sort()
# a = [1,2,3,3,5]

temp = a.sort()
# temp = None

리턴값이 없기 때문에 result에 저장되는 값이 없다.

sorted()함수는 정렬시켜서 리턴값을 새로 만든다

a = [1,3,2,5,3]
temp = sorted(a)

그렇기 때문에 이렇게 새로 받아 줘야 한다.

sort할 때 여러개의 기준으로 확인하는 방법
temp.sort(key = lambda x :(x[0], x[1]))

이런식으로 작성하면 되고, 역순으로 하고 싶다면 -부호를 사용할 수 있다.


tip for me

요즘 푸는 문제마다 테케를 다 못 맞춘다..
원래 레벨3은 빨리 풀고 다맞는 정도였는데 요며칠 안했다고 실력이 내려간건지, 요즘따라 고르는 문제마다 좀 복잡한건지
너무 조급하게 생각할 필요가 없다. 물론 매주 코테가 있긴하지만 ;;
러닝할때도 한동안 페이스 쳐치다가 되찾은 것처럼 코테 페이스도 그럴 수 있을거야
그리고 매번 틀리는게 단순 실수가 아니라 무언가를 배우니까 더 발전하고 있다

profile
you can do

0개의 댓글