-
프로그래머스_LV1_크레인 인형뽑기 게임프로그래머스 문제풀이 2020. 10. 28. 01:52728x90
문제 설명
게임개발자인 죠르디는 크레인 인형뽑기 기계를 모바일 게임으로 만들려고 합니다.
죠르디는 게임의 재미를 높이기 위해 화면 구성과 규칙을 다음과 같이 게임 로직에 반영하려고 합니다.게임 화면은 1 x 1 크기의 칸들로 이루어진 N x N 크기의 정사각 격자이며 위쪽에는 크레인이 있고 오른쪽에는 바구니가 있습니다. (위 그림은 5 x 5 크기의 예시입니다). 각 격자 칸에는 다양한 인형이 들어 있으며 인형이 없는 칸은 빈칸입니다. 모든 인형은 1 x 1 크기의 격자 한 칸을 차지하며 격자의 가장 아래 칸부터 차곡차곡 쌓여 있습니다. 게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다. 집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다. 다음 그림은 [1번, 5번, 3번] 위치에서 순서대로 인형을 집어 올려 바구니에 담은 모습입니다.
만약 같은 모양의 인형 두 개가 바구니에 연속해서 쌓이게 되면 두 인형은 터뜨려지면서 바구니에서 사라지게 됩니다. 위 상태에서 이어서 [5번] 위치에서 인형을 집어 바구니에 쌓으면 같은 모양 인형 두 개가 없어집니다.
크레인 작동 시 인형이 집어지지 않는 경우는 없으나 만약 인형이 없는 곳에서 크레인을 작동시키는 경우에는 아무런 일도 일어나지 않습니다. 또한 바구니는 모든 인형이 들어갈 수 있을 만큼 충분히 크다고 가정합니다. (그림에서는 화면표시 제약으로 5칸만으로 표현하였음)
게임 화면의 격자의 상태가 담긴 2차원 배열 board와 인형을 집기 위해 크레인을 작동시킨 위치가 담긴 배열 moves가 매개변수로 주어질 때, 크레인을 모두 작동시킨 후 터트려져 사라진 인형의 개수를 return 하도록 solution 함수를 완성해주세요.
[제한사항]
- board 배열은 2차원 배열로 크기는 5 x 5 이상 30 x 30 이하입니다.
- board의 각 칸에는 0 이상 100 이하인 정수가 담겨있습니다.
- 0은 빈 칸을 나타냅니다.
- 1 ~ 100의 각 숫자는 각기 다른 인형의 모양을 의미하며 같은 숫자는 같은 모양의 인형을 나타냅니다.
- moves 배열의 크기는 1 이상 1,000 이하입니다.
- moves 배열 각 원소들의 값은 1 이상이며 board 배열의 가로 크기 이하인 자연수입니다.
입출력 예
boardmovesresult
[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4 입출력 예에 대한 설명
입출력 예 #1
인형의 처음 상태는 문제에 주어진 예시와 같습니다. 크레인이 [1, 5, 3, 5, 1, 2, 1, 4] 번 위치에서 차례대로 인형을 집어서 바구니에 옮겨 담은 후, 상태는 아래 그림과 같으며 바구니에 담는 과정에서 터트려져 사라진 인형은 4개 입니다.
기본틀
힌트
뭔가 스크롤을 조금씩 내리면서 힌트를 얻길 바랬던 마음으로 조금씩 내리면서 참고해보자
풀이
문제를 해결하는데 4시간은 족히 걸린것 같다.
답지를 찾아보진 않았지만
질문하기를 참고하지 않으면 잠을 잘 수 없을 것 같아 봐야했다.
이전과 마찬가지로 VS CODE로 실행 후 옮기는 작업을 하였다.
이게 LV.1 이라는 것을 기억하자
1. 먼저 board 2차원 배열의 가독성을 높히면 5종류의 케릭터 얼굴이 번호로 표시되어 있음을 확인 할 수 있다.
위의 2사진을 비교해보면 이해가 쉽다.
2. board와 moves 2가지 변수를 이용하여 식을 구성해야하는데
먼저 for 중첩문으로 각자 변수의 횟수를 정할 수 있다.
여기서 바깥 for 문/ 안쪽 for 문 기준은 2가지 중 어느것을 사용해도 무방할 것 같다.
i = board를 j = moves를 사용해도 답을 구할 수 있을 것 같다.
초반 이해를 위해 range(5)를 사용하여 흐름을 파악하는 것도 좋다고 생각한다.
3. moves의 요소는 세로 인덱스 값에 영향을 주는점과 board 2차원 배열의 인덱스 번호를 이용해 접근하자.
board 는 [0][0] ~~ [4][4]까지의 인덱스번호를 가지고 있다 (5 x 5 기준)
여기서 moves 1 -> 0행 , 5 - 4행이다
이를 이용해 board의 인덱스 번호를 구성하는데 moves의 5번 요소는 4열 값에 해당하는 점을 인지
if 조건문을 구성한다
for i in moves: # [1, 5, 3, 5, 1, 2, 1, 4]
for j in range(len(board)): # 0 ~ 4
if board[j][i-1] == 0 :
## 여기서 if 에서 끝나지 않고 if else 문을 사용해준다.
## if board[][] != 0: 으로 else문을 달지 않은 방법으로는 실패하였다.
pass ## board[][] 값의 0 이라면 별도의 코드 블럭 없이 pass
else: ## board[][] 값이 0이 아닐경우,
basket.append(board[j][i-1]) ## 해당 board 인덱스 번호의 값을 basket에 추가
board[j][i-1] = 0
## 해당 번호의 값을 저장 후 해당 번호를 0으로 바꿔준다
## pop()로 삭제해보는 방법은 실패하였다
break
## 여기서 break로 반복문을 멈추지 않으면 4행 0열 값도 사라진다.
## 크레인이 한번 값을 바구니로 옮긴 후 다음 moves 값을 실행하여야 하는데
## 멈추지 않을 경우 board의 모든 값이 0으로 되며 모든 값이 바구니로 담긴다.
4. 위의 코드를 마무리 할 경우
basket =[4, 3, 1, 1, 3, 2, 4]
board = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 5, 0, 0], [0, 2, 4, 0, 2], [0, 5, 1, 3, 1]] 이 된다.추가로, 여기서는 basket은 stack구조로 같은 값의 값이 연속으로 쌓일 경우 두 값을 삭제하고 삭제된 갯수를 출력해야하하므로 바깥의 for 문이 작동하는 동안 basket에서도 if 문으로 연속으로 쌓인 두 값을 삭제해줘야 한다.
if len(basket) >= 2: ## 바구니에 값이 2개가 담기는 순간부터 검증을 해야한다
if basket[len(basket)-2] != basket[len(basket)-1]:
pass
## 두 값이 같지 않을때 pass
## basket 의 값이 2개일때를 생각해보자
## basket = [4, 3] --> basket[0] == 4 , basket[1] ==3
## 앞 뒤의 인덱스번호를 비교해야하므로 len을 이용해 두 값을 비교 할 수 있으며
## -2 와 -1 // 에서 값을 잘못입력하면 인덱스 범위를 벗어나는 오류가 발생한다
else: ## 두 값이 같다면
del basket[len(basket)-2]
del basket[len(basket)-1]
count += 2
## 같을 경우 basket 안의 해당 두 값을 삭제하고 카운트 에 +2 증가를 해준다.
answer = count
## 마지막으로 answer 에 count를 할당하고 출력하면 마무리.
## 굳이 count를 만들지 않고 바로 answer += 2 를해도 작동한다.
출처 :
programmers.co.kr/learn/courses/30/lessons/64061
728x90'프로그래머스 문제풀이' 카테고리의 다른 글
스택/큐_주식가격_python (0) 2021.04.27 힙_더 맵게_python (0) 2021.04.22 해시_전화번호 목록_python (0) 2021.04.19 스택/큐_다리를 지나는 트럭_python (0) 2021.04.13 프로그래머스_LV1_두 개 뽑아서 더하기 (0) 2020.10.27