[programmers/js] 기둥과 보 설치

승민·2025년 4월 19일

알고리즘

목록 보기
157/171

기둥과 보 설치

https://school.programmers.co.kr/learn/courses/30/lessons/60061

문제 설명

"죠르디"는 기둥과 보를 이용하여 벽면 구조물을 자동으로 세우는 로봇을 개발할 계획인데, 그에 앞서 로봇의 동작을 시뮬레이션 할 수 있는 프로그램을 만들고 있습니다.
프로그램은 2차원 가상 벽면에 기둥과 보를 이용한 구조물을 설치할 수 있는데, 기둥과 보는 길이가 1인 선분으로 표현되며 다음과 같은 규칙을 가지고 있습니다.

기둥은 바닥 위에 있거나 보의 한쪽 끝 부분 위에 있거나, 또는 다른 기둥 위에 있어야 합니다.
보는 한쪽 끝 부분이 기둥 위에 있거나, 또는 양쪽 끝 부분이 다른 보와 동시에 연결되어 있어야 합니다.

벽면의 크기 n, 기둥과 보를 설치하거나 삭제하는 작업이 순서대로 담긴 2차원 배열 build_frame이 매개변수로 주어질 때, 모든 명령어를 수행한 후 구조물의 상태를 return 하도록 solution 함수를 완성해주세요.

조건 요약

기둥(0)은 다음 중 하나일 때 설치 가능

  1. 바닥 위 (y === 0)
  2. 다른 기둥 위 (아래 좌표에 기둥)
  3. 보의 끝 위 (현재 좌표에 보 or 왼쪽 좌표에 보)

보(1)는 다음 중 하나일 때 설치 가능

  1. 한쪽 끝이 기둥 위 (현재 좌표 아래 or 오른쪽 아래에 기둥)
  2. 양쪽 끝이 보에 연결됨 (왼쪽, 오른쪽 모두 보)

풀이

구조물 정보를 저장할 배열 answer를 선언

build_frame의 각 명령을 순차적으로 처리

  • 설치 명령 → 구조물 추가 후 canBuild() 검사 → 안되면 되돌림
  • 삭제 명령 → 임시 삭제 후 canBuild() 검사 → 안되면 되돌림
  • canBuild()는 현재 구조물 배열 상태가 모든 조건을 만족하는지 확인

정답은 (x 오름차순 → y 오름차순 → 기둥 우선) 기준으로 정렬

// 20:45 ~
function solution(n, build_frame) {
    const answer = [];
    
    const canBuild = () => {
        for (const [x, y, type] of answer) {
            if (type === 0) { // 기둥
                if (
                    y === 0 || // 바닥 
                    answer.some(([nx, ny, t]) => (t === 1 && ((nx === x - 1 && ny === y) || (nx === x && ny === y)))) || // 보 위에
                    answer.some(([nx, ny, t]) => (t === 0 && nx === x && ny === y - 1)) //  밑에 기둥
                   ) continue;
                    return false;
            } else { // 보
                if (
                    answer.some(([nx, ny, t]) => (t === 0 && ((nx === x && ny === y - 1) || (nx === x + 1 && ny === y - 1)))) || // 기둥 위
                    (
                        answer.some(([nx, ny, t]) => (t === 1 && nx === x - 1 && ny === y)) &&
                        answer.some(([nx, ny, t]) => (t === 1 && nx === x + 1 && ny === y))
                    ) // 양 쪽이 보
                ) continue;
                return false;
            }
        }
        
        return true;
    }
    
    for (const [x, y, type, cmd] of build_frame) {
        if (cmd === 1) { // 설치
            answer.push([x, y, type]);
            if (!canBuild()) answer.pop();
        } else { // 삭제
            const idx = answer.findIndex(([a, b, c]) => a === x && b === y && c === type);
            const temp = answer.splice(idx, 1);
            if (!canBuild()) answer.push(temp[0]);
        }
    }
    
    return answer.sort((a, b) => a[0] - b[0] || a[1] - b[1] || a[2] - b[2]);
}

0개의 댓글