[프로그래머스] Lv.1 크레인 인형뽑기 게임 (JavaScript)

문규찬·2023년 9월 17일
0
post-thumbnail

✅ 문제

게임 화면은 "1 x 1" 크기의 칸들로 이루어진 "N x N" 크기의 정사각 격자이며 위쪽에는 크레인이 있고 오른쪽에는 바구니가 있습니다. (위 그림은 "5 x 5" 크기의 예시입니다). 각 격자 칸에는 다양한 인형이 들어 있으며 인형이 없는 칸은 빈칸입니다. 모든 인형은 "1 x 1" 크기의 격자 한 칸을 차지하며 격자의 가장 아래 칸부터 차곡차곡 쌓여 있습니다. 게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다. 집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다. 다음 그림은 [1번, 5번, 3번] 위치에서 순서대로 인형을 집어 올려 바구니에 담은 모습입니다.

만약 같은 모양의 인형 두 개가 바구니에 연속해서 쌓이게 되면 두 인형은 터뜨려지면서 바구니에서 사라지게 됩니다. 위 상태에서 이어서 [5번] 위치에서 인형을 집어 바구니에 쌓으면 같은 모양 인형 두 개가 없어집니다.

✅ 예시

  • 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]]
  • moves : [1,5,3,5,1,2,1,4]
  • result : 4

인형의 처음 상태는 문제에 주어진 예시와 같습니다. 크레인이 [1, 5, 3, 5, 1, 2, 1, 4] 번 위치에서 차례대로 인형을 집어서 바구니에 옮겨 담은 후, 상태는 아래 그림과 같으며 바구니에 담는 과정에서 터트려져 사라진 인형은 4개 입니다.

✅ 풀이

처음 문제를 읽어보고 가장 먼저 들었던 생각은
1. 각 인형이 담긴 배열들이 있을테고
2. moves의 배열을 순회하며 그에 맞는 인형 배열을 찾자
3. 인형배열을 찾았으면 마지막 요소를 하나 가지고와서 (크레인) 새로운 배열에(바구니) 담아주자

moves의 요소와 매칭이되는 인형이 담긴 배열을 찾기 위해 { 인형배열1:[], 인형배열2:[] } 형태의 key:value로 객체의 모습이면 되겠다? 라는 큰 그림 정도만 그려졌다

예시를 보면 위에서 크레인이 움직이며 인형을 가져오는걸 그냥 해당 배열의 pop()정도로 생각해보니 moves가 1일때 board의 모든 배열 요소들의 [0]번째를 한번씩 다 보면서 처음으로 값이 나오면!? 바구니에 담는것보다

이렇게 키와 벨류의 형태로 배열을 돌려놓고, 0이 아닌것만 배열에 넣자 생각했다

function solution(board,moves){
  let obj={}
  
  for(let i=board.length; i>=i; i--){
    for(let j=1; j<=board.length; j++){
      if(!obj[j]) obj[j]=[]
      if(board[i-1][j-1]!==0) obj[j].push(board[i-1][j-1])
    }
  }
}


//console.log(obj
{
  '1': [ 3, 4 ],
  '2': [ 5, 2, 2 ],
  '3': [ 1, 4, 5, 1 ],
  '4': [ 3, 4 ],
  '5': [ 1, 2, 1, 3 ]
}

이제 인형이 담긴 배열이 key를 알고있고 moves를 순회하면서 바구니에 넣으면 될 것 같다.

function solution(board,moves){
  let obj={}
  let result=[]
  let count=0
  for(let i=board.length; i>=1; i--){
    for(let j=1; j<=board.length; j++){
      if(!obj[j]) obj[j]=[]
      if(board[i-1][j-1]!==0) obj[j].push(board[i-1][j-1])
    }
  }
  
  for(let pick of moves){
	let pickDoll= obj[pick].pop()
    //1
    if(pickDoll!==undefined) result.push(pickDoll)
    //2
    if(result[result.length-1]===result[result.length-2]){ 
    result.splice(-2,2) 
    count+=2
    }
  }
  return count
}

바구니에 moves 순서대로 요소가 들어오는데 끝 두개가 같을땐 인형이 팡 터진다 (2번)
그리고 바구니에 push하기전에 크레인이 인형을 뽑으려는데 인형이 없을때는 (1번) undefined(배열의 인형이 없기때문) 라 따로 처리를 해줬다

결국 최종 바구니의 인형이 몇개인지를 return 하는줄 알았는데, 어림없지..ㅎ 인형이 몇개나 터졌나를 return 하는거라 따로 count 변수를 만들어줬다.

이렇게 작성하면 테스트케이스의 return 값은 제대로 나온다
역시나 또! 어림없지 다른 케이스는 통과를 못하나보다

board,moves가 ([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [1, 2, 3, 4])

인형뽑기를 하려는데 인형이 하나도 없는경우의 예외처리를 안해준 것 같다.

✅ 내가 작성한 답안

function solution(board,moves){
  let obj={}
  let result=[]
  let count=0
  for(let i=board.length; i>=1; i--){
    for(let j=1; j<=board.length; j++){
      if(!obj[j]) obj[j]=[]
      if(board[i-1][j-1]!==0) obj[j].push(board[i-1][j-1])
    }
  }
  for(let pick of moves){
    let pickDoll= obj[pick].pop()
    if(pickDoll!==undefined) result.push(pickDoll)
    if(!result.length) return count
    if(result[result.length-1]===result[result.length-2]){ 
    result.splice(-2,2) 
    count+=2
    }
  }
  return count
}

블로그를 다시 열심히 해보려고 오랜만에 벨로그 들어와서 내가 쓴 글들을 읽어보는데 내가 작성한 글도 다시 읽어보니까 혼잣말로 "뭐라는거야" ...ㅎㅎㅎㅎㅎ 대부분 글들이 나만 기억하려고 대충 메모의 개념이었던 것 같다 앞으로는 포스팅 하나를 하더라도 제대로!

여튼! 첫 게시글을 뭘로 할까 고민중에 요즘에는 퇴사후에 프로그래머스 코딩테스트 연습? 에 빠져있는 것 같아 어제 풀었던 문제를 첫 게시글로 써봤다. 시작은 코딩테스트 연습이라기 보단, 공부나 작업 시작전에 뇌풀기? 정도로 레벨0 부터 한,두문제 풀기 시작했는데 문제 하나하나 쌓여가다 보니
욕심도 생기고, 알고있다고 생각했던 단순 문도 응용할 수 있는 사고력이 생기는 것 같은?
문제를 풀때마다 순위를 적어놓는데 시작은 47899위 였는데 어느새 14409위 1000위 안으로 들어가거파....

당분간은 프로그래머스 연습문제 및 코어개념에 대한 포스팅을 할 예정이다.

출처 https://school.programmers.co.kr/learn/courses/30/lessons/64061

0개의 댓글