Javascript

[프로그래머스 Level1] 크레인 인형뽑기 게임 - 나의 코드(Javascript)

728x90
반응형

🚨문제

https://programmers.co.kr/learn/courses/30/lessons/64061?language=javascript

 

 

🔅예제 이해

입출력 예

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

[[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]] 가 어떻게 생긴 건지 이해가 잘 안 되었는데,

이런저런 경우의 수로 생각해보니까 row값으로 생각하면 되더라!

00000

00103

02501

.. 이런식으로 말이다. 아래 그림을 보면 더 이해하기 쉽다.

 

입출력 예에 대한 설명

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

 

 

☺️나의 코드

function solution(board, moves) {

    //1. 세로로 값이 정렬되도록 정리
    var cols = [];
    for (let i = 0; i < board.length; i++) {
        cols[i] = [];
    }
    for(let t = 0 ; t < board.length; t++){
         for(const num in board[t]){
             cols[num].push(board[t][num])
         }
    }
    //console.log(cols)

    //2. 빈칸인 0값 제거
    let filtered = []
    for(const col of cols){
        filtered.push(col.filter((e) => e !== 0));
    }
    //console.log(filtered)

    //3. 크레인으로 잡아서 바구니로 이동하기
    let basket = [];
    for(const move of moves){
        //집게가 잡은 것 
        const item = filtered[move-1][0];
        //바구니에 담기
        if(item){
            basket.push(item);
        }
        //바구니에 담긴 값 목록에서 제거 (첫번째 값 삭제)
        filtered[move-1].shift();
    }
    console.log(basket)

    //4. 바구니에서 중복되는거 터트리기
    var countPop = 0;//터진 횟수
    //터질 것이 없을때까지 반복되어야 함으로 do~while문 실행
    do{
        var isPop = false;
        for (let i = 0; i < basket.length; i++) {
        const nextIndex = i+1;
        const lastIndex = basket.length
        //마지막 값만 제외하고
            if(nextIndex != lastIndex){
                //다음 값이랑 같은 경우
                if(basket[i] == basket[nextIndex]){
                    //해당하는 값 두개 삭제
                    basket.splice(i,2);
                    isPop = true;
                    //터트린 숫자 추가, 한번 터질 때 2개가 터짐
                    countPop += 2;
                }
            }
        }
    }while(isPop); 
    //한개라도 터진 게 있는 경우, do구문을 돌려서 한번 더 검사한다.
    //터진게 없는 경우 isPop은 false가 되면서 반복문 종료

    //5. 답 도출
    var answer = countPop;
    return answer;
}

 

 

❗️ 풀이 순서

  1. 세로로 값이 정렬되도록 정리

row로 배열 값이 들어있길래 나중에 빼고 선택하기 쉽기 위해 세로로 재 정렬해주었다.

 

  1. 빈칸인 0 값 제거

0은 빈칸인데, 크레인은 빈칸은 그냥 지나치고 맨 위의 값만 가져오면 되기에, 0을 배열에서 제거했다.

배열.push(col.filter((e) => e !== 0));

 

  1. 크레인으로 잡아서 바구니로 이동하기

moves의 순서에 맞게 세로로 재 정렬한 배열에서 가장 위의 값을 가져와 바구니 배열에 넣어주었다.

그리고 세로 배열에서 빼낸 값은 배열에서 삭제했다.

배열.shift() : 배열의 첫 번째 값을 제거

 

  1. 바구니에서 중복되는 거 터트리기

바구니의 값을 for문으로 검사해서, 해당 값과 다음 인덱스 값이 같은 경우 두 개 값 모두 삭제하기

이때 고민한 게 이 검사를 한 번만 하는 게 아니라 해당하는 게 있으면 여러 번 해야 했다.

예를 들어 바구니에 담긴 값이 [4,3,1,1,3,2,4]라고 할 때

터지는 건 두 번 일어나야 한다. 처음 터지고 나면 1이 사라져서 [4,3,3,2,4], 두 번째 터지면 3이 사라져서 [4,2,4]

for로 한 번만 돌리는 게 아니라 또 돌려야 하는데, 어떻게 할까 하다가 우선 실행되고 그다음에 조건에 따라 동일한 구문을 돌릴 수 있는 do while문을 생각하였다.

배열.splice(i,2) : 배열에서 i번째 인덱스부터 2개 삭제 / 배열 내 특정 인덱스에서 값 삭제

 

+ 중복되는 숫자를 찾는 방식으로 나는 배열을 사용했지만, 배열을 문자열로 바꾼 다음 정규식으로 찾아내는 것도 괜찮은 것 같았다.

var num = "1234a12345ab";
var regexp = /[0-9]{5}/g;
alert(num.match(regexp));

#정규식 풀이

/

[0-9] 0부터 9까지의 숫자

{2} {연속될 개수}

/g

 

#정규식 응용

/

[a-z] a부터 z까지의 소문자

{2} {연속될 개수}

/g

 

 

 



728x90
반응형