본문 바로가기

코딩테스트

[프로그래머스] level2. [1차] 프렌즈4블록 (javascript)

반응형

문제

블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 "프렌즈4블록".
같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임이다.

만약 판이 위와 같이 주어질 경우, 라이언이 2×2로 배치된 7개 블록과 콘이 2×2로 배치된 4개 블록이 지워진다. 같은 블록은 여러 2×2에 포함될 수 있으며, 지워지는 조건에 만족하는 2×2 모양이 여러 개 있다면 한꺼번에 지워진다.

블록이 지워진 후에 위에 있는 블록이 아래로 떨어져 빈 공간을 채우게 된다.

만약 빈 공간을 채운 후에 다시 2×2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복하게 된다.

위 초기 배치를 문자로 표시하면 아래와 같다.

TTTANT
RRFACC
RRRFCC
TRRRAA
TTMMMF
TMMTTJ
각 문자는 라이언(R), 무지(M), 어피치(A), 프로도(F), 네오(N), 튜브(T), 제이지(J), 콘(C)을 의미한다

입력으로 블록의 첫 배치가 주어졌을 때, 지워지는 블록은 모두 몇 개인지 판단하는 프로그램을 제작하라.

나의 풀이

function solution(m, n, board) {
    var answer = 0;
    let end = 0;

    board = board.map((el)=>el.split(""))

    function judge(){

        //근처 4개가 동일한 부분 0으로 체크
        for(let i = 0 ; i < m-1; i++){
            for(let j = 0 ; j < n-1; j++){
                if (board[i][j] !=="*" ){
                    if( board[i][j] == board[i][j+1] && board[i][j] == board[i+1][j] && board[i][j] == board[i+1][j+1]){
                    board[i][j] = 0;
                    }
                }
            }
        }

        //0 오른쪽, 아래, 대각선은 0이 아니면 1로 처리
        for(let i = 0 ; i < m-1; i++){
            for(let j = 0 ; j < n-1; j++){
                if( board[i][j] == 0 ){
                    if ( board[i][j+1] !== 0){ 
                        board[i][j+1] =1;
                    }
                    if ( board[i+1][j] !== 0){ 
                        board[i+1][j] =1;
                    }
                    if ( board[i+1][j+1] !== 0){ 
                        board[i+1][j+1] =1;
                    }
                }
            }
        }
        //숫자인 부분은 윗 배열의 알파벳으로 대체되야됨. 빈공간 "*"으로 비워주기
        let flag =0; 
        for(let i = 0 ; i < m; i++){
            for(let j = 0 ; j < n; j++){
                if( !isNaN(board[i][j]) ){
                    flag =1;
                    if( i == 0){
                        board[i][j] = "*"
                    } else{
                        board[i][j] = board[i-1][j]
                        board[i-1][j] = "*"
                    }
                }
            }
        }
        if (flag == 0){
            end = 1
        }

        // 첫줄에 문자가 있는데 밑에서 제거가 되면 문자가 안내려가는 에러 해결을 위한 구간(+5번 케이스)
        function senddown(){
            for(let i = 1 ; i < m; i++){
                for(let j = 0 ; j < n; j++){
                    if(board[i][j] == "*"){
                        board[i][j] = board[i-1][j]
                        board[i-1][j] = "*"
                    }
                }
            }
        }
        while(true){
            let flag2 = 0;
            for(let i = 1 ; i < m; i++){
                for(let j = 0 ; j < n; j++){
                    if(board[i][j] == "*" && board[i-1][j] !=="*" ){
                        senddown(); 
                        flag2 = 1;       
                    }
                }
            }
            if (flag2 == 0) {
                break;
            }
        }


    }


    // 안에서 숫자로 변환 처리 없을때까지(즉, 더이상 작업이 없을때까지) 반복, flag를 통해 구현
    while(end != 1){
        judge()
    }

    //"*"갯수 카운팅
    board.map((el)=>el.map((element)=>{
        if (element == "*"){
            answer +=1;
        }
    }))

    return answer;
}

다른이들의 정답

function solution(m, n, board) {
    board = board.map(v => v.split(''));

    while (true) {
        let founded = [];

        // 찾기
        for (let i = 1; i < m; i++) {
            for (let j = 1; j < n; j++) {
                if (board[i][j] && board[i][j] === board[i][j - 1] && board[i][j] === board[i - 1][j - 1] && board[i][j] === board[i - 1][j]) {
                    founded.push([i, j]);
                }
            }
        }

        if (! founded.length) return [].concat(...board).filter(v => ! v).length;

        // 부수기
        founded.forEach(a => {
            board[a[0]][a[1]] = 0;
            board[a[0]][a[1] - 1] = 0;
            board[a[0] - 1][a[1] - 1] = 0;
            board[a[0] - 1][a[1]] = 0;
        });

        // 재정렬
        for (let i = m - 1; i > 0; i--) {
            if (! board[i].some(v => ! v)) continue;

            for (let j = 0; j < n; j++) {
                for (let k = i - 1; k >= 0 && ! board[i][j]; k--) {
                    if (board[k][j]) {
                        board[i][j] = board[k][j];
                        board[k][j] = 0;
                        break;
                    }
                }
            }
        }
    }
}

최근들어 some을 이용한 배열 정리하는 것을 자주 보는 것 같다. some함수를 활용해보자!

반응형