문제출처 : 코드테스트
게임 화면은 "1 x 1" 크기의 칸들로 이루어진 "N x N" 크기의 정사각 격자이며 위쪽에는 크레인이 있고 오른쪽에는 바구니가 있습니다. (위 그림은 "5 x 5" 크기의 예시입니다). 각 격자 칸에는 다양한 인형이 들어 있으며 인형이 없는 칸은 빈칸입니다. 모든 인형은 "1 x 1" 크기의 격자 한 칸을 차지하며 격자의 가장 아래 칸부터 차곡차곡 쌓여 있습니다. 게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다. 집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다. 다음 그림은 [1번, 5번, 3번] 위치에서 순서대로 인형을 집어 올려 바구니에 담은 모습입니다.
만약 같은 모양의 인형 두 개가 바구니에 연속해서 쌓이게 되면 두 인형은 터뜨려지면서 바구니에서 사라지게 됩니다. 위 상태에서 이어서 [5번] 위치에서 인형을 집어 바구니에 쌓으면 같은 모양 인형 두 개가 없어집니다.
크레인 작동 시 인형이 집어지지 않는 경우는 없으나 만약 인형이 없는 곳에서 크레인을 작동시키는 경우에는 아무런 일도 일어나지 않습니다. 또한 바구니는 모든 인형이 들어갈 수 있을 만큼 충분히 크다고 가정합니다. (그림에서는 화면표시 제약으로 5칸만으로 표현하였음)
게임 화면의 격자의 상태가 담긴 2차원 배열 board와 인형을 집기 위해 크레인을 작동시킨 위치가 담긴 배열 moves가 매개변수로 주어질 때, 크레인을 모두 작동시킨 후 터트려져 사라진 인형의 개수를 return 하도록 solution 함수를 완성해주세요.
[제한사항]
board | moves | result |
---|---|---|
[[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개 입니다.
다음고 같은 흐름으로 문제 해결을 제시하였다.
1. moves의 value 값을 board의 index 값을 말한다.
2. 0일때는 넘어가고 숫자가 있는경우에는 다른 그릇에 담는다.
3. 담긴 숫자가 같은 수가 두번 나올 경우에 그 숫자는 삭제되고 point가 쌓인다.
작성된 코드는 다음과 같다.
//문제에서 주어진 board와 moves
let board = [
[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]
]
let moves = [1,5,3,5,1,2,1,4]
function solution(board, moves) {
let answer = []; //그릇으로 전환
let cnt = 0;
let point = 0;
//먼저 moves만큼 for구문을 반복시켜서 board index의 위치를 정하자
for (let i = 0; i < moves.length; i++) {
//다음 board만큼 반복 시켜서 moves의 위치에서 5개의 배열을 전부 검사한자
for (let j = 0; j < board.length; j++) {
//0이 아닌 수를 다른 곳에 담자. answer를 배열로 바꾸면 되겠다.
if(board[j][moves[i]-1] !== 0 && cnt === i){
//이렇게 담으면 0이 아닐 때 board[j]의 값이 추가로 담긴다. 값이 담기고 바로 다음 순서로 넘어가도록 cnt를 만들어서 막아주자
cnt ++; //다음 moves로 넘어간다.
//answer += board[j][moves[i]-1]; // 아래 조건문과 중복됨으로 삭제
//값을 단순히 축척시키는 것이 아닌 배열로 만들어야 한다.
//담긴 배열이 중복 수 가 나오면 point를 올리고 안나오면 담아내는 조건문을 만들자.
if(answer[answer.length-1] === board[j][moves[i]-1]){
//point 변수를 추가하여 값을 담자
answer.pop(); // 중복될 때 숫자 제거.
point += 2;
}else{
answer.push(board[j][moves[i]-1])
}
// 위 조건을 거치고 숫자가 빠질때 0이 채워져야 한다.
board[j][moves[i]-1] = 0;
}
}
}
// answer가 아닌 point를 return 시켜야지 원하는 result를 출력한다.
return point;
}
solution(board,moves)
위와 같이 사고를 하였음에도 코드 작성에는 애로사항이 많았다.
특히 잘 해결되지 않는 부분은
1. 중복된 수를 같이 잡아내어 중복을 방지하는 코드를 어떻게 해야할지
2. answer에 값을 담을때 배열 형식이 아닌 문자열로 담아내어 값이 제대로 출력되지 않는 점.
3. 값을 담아내고 그 값을 pop 시키고 board 배열 자체에 0을 집어 넣지 않아 다시 또 중복으로 값을 담아낸 점
위 3가지가 해결되지 않아 다른 사람의 코드를 참고 하여 해결하였다.
아직 스스로 해결할 능력이 부족한 것 같아 같은 코드를 3번 ~ 4번 스스로 작성해보았다.
위와 같은 비슷한 문제뿐 아니라 비슷한 알고리즘으로 해결해야 할 문제는 많을 것이다.
'포기하지말자' 계속 전진하자.