프로그래머스-카카오: 기둥과 보(Javascript)
문제링크 : https://programmers.co.kr/learn/courses/30/lessons/60061
문제
문제 제한사항은 링크에서 확인
문제를 해결한 방법
같은 지점에 기둥과 보가 동시에 존재하는 경우도 있기 때문에 3차원 배열을 사용했습니다.
floor[0][x][y]
- 좌표 x,y에 기둥이 있으면true
, 없으면false
floor[1][x][y]
- 좌표 x,y에 보가 있으면true
, 없으면false
설치하는 경우
-
기둥 -
validColumns()
함수를 이용하여 해당 좌표에서 기둥을 설치할 수 있는지 확인function validColumns(floor, x, y) { if (y === 0) { // 바닥인 경우 return true; } else if (floor[0][x][y - 1]) { // 밑에 기둥이 있는 경우 return true } else if (x > 0 && floor[1][x - 1][y]) { // 왼쪽에 보가 있는 경우 return true; } else if (floor[1][x][y]) { // 보 위에 있는 경우 return true; } return false; }
- 바닥인 경우
- 밑에 기둥이 있는 경우
- 왼쪽에 보가 있는 경우
- 기둥이 보 바로 위에 있는 경우
-
보 -
validBeams()
함수를 이용하여 해당 좌표에 보를 설치할 수 있는지 확인function validBeams(floor, n, x, y) { // 기둥 위에 있는 경우 if (floor[0][x][y - 1]) { return true; } // 우측 아래 기둥이 있는 경우 else if (x < n && floor[0][x + 1][y - 1]) { return true; } // 양 옆에 보가 있는 경우 else if (x > 0 && x < n && floor[1][x - 1][y] && floor[1][x + 1][y]) { return true; } return false; }
- 바로 밑에 기둥이 있는 경우
- 우측 아래에 기둥이 있는 경우
- 양 옆에 보가 있는 경우
삭제하는 경우
-
기둥 - 해당 위치에 기둥을 제거하고 주변 구조물이 설치 가능한지 검사
function removeColumns(floor, n, x, y) { floor[0][x][y] = false; // 일단 기둥을 제거하고 주변 구조물 유효성 검사 // 위에 기둥이 있는 경우 if (y < n && floor[0][x][y + 1] && !validColumns(floor, x, y + 1)) { floor[0][x][y] = true; } // 위에 보가 있는 경우 else if (y < n && floor[1][x][y + 1] && !validBeams(floor, n, x, y + 1)) { floor[0][x][y] = true; } // 좌측 위에 보가 있는 경우 else if (x > 0 && floor[1][x - 1][y + 1] && !validBeams(floor, n, x - 1, y + 1)) { floor[0][x][y] = true; } }
- 위에 기둥이 존재한다면
validColumns()
으로 확인 - 위에 보가 존재한다면
validBeams()
으로 확인 - 좌측 대각선 위에 보가 존재하면
validBeams()
으로 확인 - 모든 조건을 통과한다면 제거
- 위에 기둥이 존재한다면
-
보 - 해당 위치에 보를 제거하고 주변 구조물이 설치 가능한지 검사
function removeBeams(floor, n, x, y) { floor[1][x][y] = false; // 일단 보를 제거하고 주변 구조물 유효성 검사 // 현재 위치에 기둥이 존재하는 경우 if (floor[0][x][y] && !validColumns(floor, x, y)) { floor[1][x][y] = true; } // 우측에 기둥이 존재하는 경우 else if (x < n && floor[0][x + 1][y] && !validColumns(floor, x + 1, y)) { floor[1][x][y] = true; } // 양 옆에 보가 존재하는 경우 else if (x > 0 && x < n && floor[1][x - 1][y] && floor[1][x + 1][y]) { // 둘 중에 하나라도 안되면 true if (!validBeams(floor, n, x - 1, y) || !validBeams(floor, n, x + 1, y)) { floor[1][x][y] = true; } } // 우측에만 보가 존재하는 경우 else if (x < n && floor[1][x + 1][y] && !validBeams(floor, n, x + 1, y)) { floor[1][x][y] = true; } // 좌측에만 보가 존재하는 경우 else if (x > 0 && floor[1][x - 1][y] && !validBeams(floor, n, x - 1, y)) { floor[1][x][y] = true; } }
- 현재 위치에 기둥이 존재한다면
validColumns()
으로 확인 - 우측에 기둥이 존재한다면
validColumns()
으로 확인 - 양옆에 보가 존재한다면 양쪽에
validBeams()
으로 확인 - 우측에만 보가 존재한다면
validBeams()
으로 확인 - 좌측에만 보가 존재한다면
validBeams()
으로 확인 - 모든 조건을 통과한다면 제거
- 현재 위치에 기둥이 존재한다면
소스 코드 (Javascript)
function validColumns(floor, x, y) {
if (y === 0) { // 바닥인 경우
return true;
} else if (floor[0][x][y - 1]) { // 밑에 기둥이 있는 경우
return true
} else if (x > 0 && floor[1][x - 1][y]) { // 왼쪽에 보가 있는 경우
return true;
} else if (floor[1][x][y]) { // 보 위에 있는 경우
return true;
}
return false;
}
function validBeams(floor, n, x, y) {
// 기둥 위에 있는 경우
if (floor[0][x][y - 1]) {
return true;
}
// 우측 아래 기둥이 있는 경우
else if (x < n && floor[0][x + 1][y - 1]) {
return true;
}
// 양 옆에 보가 있는 경우
else if (x > 0 && x < n && floor[1][x - 1][y] && floor[1][x + 1][y]) {
return true;
}
return false;
}
function removeColumns(floor, n, x, y) {
floor[0][x][y] = false; // 일단 기둥을 제거하고 주변 구조물 유효성 검사
// 위에 기둥이 있는 경우
if (y < n && floor[0][x][y + 1] && !validColumns(floor, x, y + 1)) {
floor[0][x][y] = true;
}
// 위에 보가 있는 경우
else if (y < n && floor[1][x][y + 1] && !validBeams(floor, n, x, y + 1)) {
floor[0][x][y] = true;
}
// 좌측 위에 보가 있는 경우
else if (x > 0 && floor[1][x - 1][y + 1] && !validBeams(floor, n, x - 1, y + 1)) {
floor[0][x][y] = true;
}
}
function removeBeams(floor, n, x, y) {
floor[1][x][y] = false; // 일단 보를 제거하고 주변 구조물 유효성 검사
// 현재 위치에 기둥이 존재하는 경우
if (floor[0][x][y] && !validColumns(floor, x, y)) {
floor[1][x][y] = true;
}
// 우측에 기둥이 존재하는 경우
else if (x < n && floor[0][x + 1][y] && !validColumns(floor, x + 1, y)) {
floor[1][x][y] = true;
}
// 양 옆에 보가 존재하는 경우
else if (x > 0 && x < n && floor[1][x - 1][y] && floor[1][x + 1][y]) {
// 둘 중에 하나라도 안되면 true
if (!validBeams(floor, n, x - 1, y) || !validBeams(floor, n, x + 1, y)) {
floor[1][x][y] = true;
}
}
// 우측에만 보가 존재하는 경우
else if (x < n && floor[1][x + 1][y] && !validBeams(floor, n, x + 1, y)) {
floor[1][x][y] = true;
}
// 좌측에만 보가 존재하는 경우
else if (x > 0 && floor[1][x - 1][y] && !validBeams(floor, n, x - 1, y)) {
floor[1][x][y] = true;
}
}
function solution(n, build_frame) {
const answer = [];
const floor = new Array(2).fill(0).map(v => new Array(n + 1));
for (let i = 0; i <= n; i++) {
floor[0][i] = new Array(n + 1);
floor[1][i] = new Array(n + 1);
}
for (let i = 0; i < build_frame.length; i++) {
const [x, y, a, b] = build_frame[i];
if (b === 1) {
if (a === 0) {
if (validColumns(floor, x, y)) {
floor[0][x][y] = true;
}
} else {
if (validBeams(floor, n, x, y)) {
floor[1][x][y] = true;
}
}
} else {
if (a === 0) {
removeColumns(floor, n, x, y);
} else {
removeBeams(floor, n, x, y);
}
}
}
for (let i = 0; i < 2; i++) {
for (let x = 0; x <= n; x++) {
for (let y = 0; y <= n; y++) {
if (floor[i][x][y]) {
answer.push([x, y, i]);
}
}
}
}
// 출력 조건에 맞게 정렬
answer.sort((a, b) => {
if (a[0] === b[0]) {
if (a[1] === b[1]) {
return a[0] - b[0];
}
return a[1] - b[1];
}
return a[0] - b[0];
})
return answer;
}
Comments