python | 카카오 크레인 인형 뽑기

yeeun lee·2020년 6월 28일
3

프로그래머스에 올라온 카카오 개발자 겨울 인턴십 코테 문제를 풀어보았다. 가장 쉬운 문제라는(...) 크레인 인형 뽑기 게임을 파이썬으로 풀었는데, 문제를 초반에 어렵게 접근해서 애를 먹었다 😞

문제

게임 화면의 격자의 상태가 담긴 2차원 배열 board와 인형을 집기 위해 크레인을 작동시킨 위치가 담긴 배열 moves가 매개변수로 주어질 때, 크레인을 모두 작동시킨 후 터트려져 사라진 인형의 개수를 return 하도록 solution 함수를 완성해주세요.

첫 번째 접근

처음에는 아래와 같이 접근했다.

  • 2차원 배열에서 index를 잡아주고
  • index value가 0이 아니면 bucket에 넣은 뒤
  • bucket에 인형이 다 쌓이면 인접한 숫자끼리 제거하는 식의 로직

아래 문제는 배열이 5x5 사이즈일 때는 통과가 되는데, 정답을 제출하면 다른 많은 문제에서 실패가 뜬다.

처음에 for i in rage(10)이 0부터 10까지라고 착각해서 len(board)에서 -1를 해주려고 했다. 근데 자꾸 index out of range error가 떠가지구 찾아보니까... 0부터 10번째까지 ( = 9번째 인덱스까지) 돌리는거였다.

# 실패 
def solution(board, moves):
    bucket = []
    for move in moves:
        for i in range(len(board)):
        
            # moves 배열의 값들이 1부터 시작하는 자연수로 되어있기 때문에 move-1
            # 인덱스로 쓰기 위해서는 0~n 형태여야 하기 때문에 -1를 빼줌
            if board[i][move-1] > 0:
                bucket.append(board[i][move-1])
                board[i][move-1] = 0
                
                # 0이 아닌 숫자를 찾으면 두 번째 for loop를 나와야 함
                # 안 나오면 더 밑에 있는 인형까지 주워올 수 있으니 주의! 
                break
                
    answer = [] 

    # 시작점을 1로 설정하고, 같은 인형이 나올 때마다 해당 인형을 빼준 뒤에 
    # 다시 버켓의 처음으로 돌아갈 수 있도록 
    i = 1
    while i < len(bucket):
        if bucket[i-1] == bucket[i]:
            answer.append(bucket[i])
            bucket.remove(bucket[i])
            bucket.remove(bucket[i-1])
            i = 1
        else:
            i += 1
    return len(answer)*2

그런데 1,2,3,5번만 통과하고 계속 다른 것은 실패했다 😭😭😭😭
처음에는 이유를 몰라서 그냥 다른 방법을 찾았는데, 만약 같은 인형이 2개 이상으로 중복된다면?이 갑자기 생각났다! 그러니까 같은 인형이 엄~청 많이 나올 수 있는건데, 내가 짠 코드는 예시에서 두 개의 인형이 중복될 때만 생각한 것이다.... (바보)

두 번째 접근

애초에 버켓에 넣을 때 가장 마지막 것과 비교해서 빼주면 불필요한 반복문(심지어 무한 루프에 빠질 수 있는 while)을 쓰지 않아도 되기 때문에, 코드의 복잡도가 훨씬 더 감소한다.

아래 코드로 다시 짜보니 바로 통과가 좌르륵 떠서 뿌듯했당 💕

# 성공!
def solution(board, moves):
    bucket = []
    answer = []
    for move in moves:
        for i in range(len(board)):
            if board[i][move-1] > 0:
                bucket.append(board[i][move-1])
                board[i][move-1] = 0
                if bucket[-1:] == bucket[-2:-1]:
                    answer += bucket[-1:]
                    bucket = bucket[:-2]
                break
    return len(answer)*2

프로그래머스가 코딩 테스트 연습하기는 굉장히 좋은 것 같은데, 각 문제를 보여주면 훨씬 더 오류에 대해 잘 해결할 수 있을 것 같다는 생각이 든다. (그러면 너무 친절한가..ㅋㅋ)

profile
이사간 블로그: yenilee.github.io

3개의 댓글

comment-user-thumbnail
2020년 8월 12일

도움 많이 됐어요ㅎㅎ감사합니다~

답글 달기
comment-user-thumbnail
2020년 11월 11일

첫번째 접근이 완전 저랑 90퍼 똑같아서 테스트케이스 1235번만 통과하고 씨름하다가 도저히 모르겠어서 검색해봤는데 큰 도움이 됐어요 ㅜㅜ
진짜 테스트케이스좀 알려주지 정말 힘드네요

답글 달기
comment-user-thumbnail
2021년 4월 13일

오 좋은 접근이네요! 그런데 if bucket[-1:] == bucket[-2:-1]:
answer += bucket[-1:]
bucket = bucket[:-2]
이렇게 해버리면 똑같은게 3개일 경우에는 2개만 처리되는게 아닌가요??

답글 달기