문제
프로그래머스 2020 KAKAO BLIND RECRUITMENT 기둥과 보 설치
언어
자바스크립트(JavaScript)
https://programmers.co.kr/learn/courses/30/lessons/60061
접근 방법
- 모든 build_frame의 요소에 대해 실행할 행동이 기둥 설치, 보 설치, 기둥 삭제, 보 삭제 인지를 구분한다.
- 가능한 행동인지 체크하고 행동을 실행한다.
- 기둥 설치의 경우 바닥이거나, 밑에 기둥이 있거나, 현재 위치를 기준으로 보가 있거나, 왼쪽 위치를 기준으로 보가 있으면 설치가 가능하다.
- 보 설치의 경우 밑에 기둥이 있거나, 오른쪽 밑에 기둥이 있거나, 양 옆에 보가 있으면 설치가 가능하다.
- 기둥이나 보의 삭제의 경우 해당 요소를 삭제한다. 이후 모든 요소에 대해서 기둥은 2-1의 조건을 만족하고 보는 2-2의 조건을 만족하면 삭제한다.
- 실행한 행동을 조건에 맞게 정렬한다.
코드
function solution(n, build_frame) {
var currentFrame = [];
for (let i=0; i<build_frame.length; i++){
if (build_frame[i][2] == 0 && build_frame[i][3] == 0){
// 기둥 삭제
destroyColumn(currentFrame, build_frame[i][0], build_frame[i][1]);
}else if (build_frame[i][2] == 0 && build_frame[i][3] == 1){
// 기둥 설치
buildColumn(currentFrame, build_frame[i][0], build_frame[i][1]);
} else if (build_frame[i][2] == 1 && build_frame[i][3] == 0){
// 보 삭제
destoryFloor(currentFrame, build_frame[i][0], build_frame[i][1]);
} else if (build_frame[i][2] == 1 && build_frame[i][3] == 1){
// 보 설치
buildFloor(currentFrame, build_frame[i][0], build_frame[i][1]);
}
}
currentFrame.sort((a,b)=>{
if (a[0]>b[0]){
return 1;
}else if (a[0]<b[0]){
return -1;
}else {
if (a[1]>b[1]){
return 1;
}else if (a[1]<b[1]){
return -1;
}else{
if (a[2]>b[2]){
return 1;
}else if (a[2]<b[2]){
return -1;
}
}
}
})
console.log(currentFrame);
return currentFrame;
}
function checkColumn(currentFrame, x, y){
let result = false;
// 바닥이면 항상 기둥 설치 가능
if (y ===0){
result = true;
// 밑에 기둥이 있으면 설치 가능
}else if (currentFrame.find(ele => (ele[0]===x && ele[1]===(y-1) && ele[2] ===0)) !== undefined){
result = true;
// 왼쪽에 보가 있으면 설치 가능
}else if (currentFrame.find(ele => (ele[0]===x-1 && ele[1]===y && ele[2] ===1)) !== undefined){
result = true;
// 그 위치에 보가 있으면 설치 가능
}else if(currentFrame.find(ele => (ele[0]===x && ele[1]===y && ele[2] ===1)) !== undefined){
result = true;
}
return result;
}
function buildColumn(currentFrame, x, y){
if (checkColumn(currentFrame, x, y)){
currentFrame.push([x,y,0]);
console.log(`${x}, ${y} 기둥 설치`);
}else{
console.log(`${x}, ${y} 기둥 설치 실패`);
}
return currentFrame;
}
function checkFloor(currentFrame, x, y){
let result = false;
// 밑에 기둥이 있으면 설치 가능
if (currentFrame.find(ele => (ele[0]===x && ele[1]===(y-1) && ele[2] ===0)) !== undefined){
result = true;
// 오른쪽 밑에 기둥이 있을때 설치 가능
}else if(currentFrame.find(ele => (ele[0]===(x+1) && ele[1]===(y-1) && ele[2] ===0)) !== undefined){
result = true;
// 왼쪽과 오른쪽에 보가 위치할 때 설치 가능
}else if ((currentFrame.find(ele => (ele[0]===x-1 && ele[1]===y && ele[2] ===1)) !== undefined)
&&(currentFrame.find(ele => (ele[0]===(x+1) && ele[1]===y && ele[2] ===1)) !== undefined)){
result = true;
}
return result;
}
function buildFloor(currentFrame, x, y){
if (checkFloor(currentFrame, x, y)){
currentFrame.push([x,y,1]);
console.log(`${x}, ${y} 보 설치`);
}else{
console.log(`${x}, ${y} 보 설치 실패`);
}
return currentFrame;
}
function destroyColumn(currentFrame, x, y){
// 현재 위치의 기둥 임시 삭제
let tempFrame = Object.assign([], currentFrame);
let findItem = tempFrame.find(ele => (ele[0]===x && ele[1]===y && ele[2] ===0));
let idx = tempFrame.indexOf(findItem);
tempFrame.splice(idx,1);
// 모든 기둥과 보의 조건을 체크
let result = true;
for (let i=0; i<tempFrame.length; i++){
if (tempFrame[i][2]==0){
if(!checkColumn(tempFrame, tempFrame[i][0], tempFrame[i][1]))
result = false;
}else {
if(!checkFloor(tempFrame,tempFrame[i][0], tempFrame[i][1]))
result = false;
}
}
if (result){
console.log(`${x}, ${y} 기둥 삭제`);
currentFrame.splice(idx,1);
}else{
console.log(`${x}, ${y} 기둥 삭제 실패`);
}
}
function destoryFloor(currentFrame, x, y){
// 현재 위치의 기둥 임시 삭제
let tempFrame = Object.assign([], currentFrame);
let findItem = tempFrame.find(ele => (ele[0]===x && ele[1]===y && ele[2] ===1));
let idx = tempFrame.indexOf(findItem);
tempFrame.splice(idx,1);
// 모든 기둥과 보의 조건을 체크
let result = true;
for (let i=0; i<tempFrame.length; i++){
if (tempFrame[i][2]===0){
if(!checkColumn(tempFrame, tempFrame[i][0], tempFrame[i][1]))
result = false;
}else {
if(!checkFloor(tempFrame,tempFrame[i][0], tempFrame[i][1]))
result = false;
}
}
if (result){
console.log(`${x}, ${y} 보 삭제`);
currentFrame.splice(idx,1);
}else{
console.log(`${x}, ${y} 보 삭제 실패`);
}
}
복기
- 처음에 조건을 완벽하게 이해하지 않고 코드를 작성해 시간을 많이 썼다.
- 다 풀고 보니 쉬운 문제 같은데 풀 때는 너무 어려웠다.
- 기둥을 삭제하거나 보를 삭제할 때에 기둥을 설치할 때 사용한 함수와 보를 설치할 때 사용한 함수를 활용하면 실수도 줄이고 시간도 덜 사용했을 것이다. 이를 인지하지 못하고 삭제 조건을 따지는 함수를 작성했었다. 이 함수는 복잡해서 작성이 오래 걸렸고 조건을 놓쳐 문제를 풀지도 못했다.
- 처음부터 기둥 설치 함수, 보 설치 함수, 삭제 시 모든 요소를 설치할 때 작성한 함수를 이용해서 체크하고 만족하면 삭제하도록 코드를 짰으면 더 쉽고 빠르게 풀었을 듯하다.
'개발 공부 > 알고리즘 문제 풀이' 카테고리의 다른 글
[프로그래머스] 크레인 인형뽑기 게임 (JavaScript) (0) | 2020.06.04 |
---|---|
[프로그래머스] [1차] 다트 게임 (JavaScript) (0) | 2020.06.02 |
[프로그래머스] [1차] 비밀지도 (JavaScript) (0) | 2020.06.02 |
[프로그래머스] 실패율 (JavaScript) (2) | 2020.06.02 |
[프로그래머스] 후보키 (JavaScript) (4) | 2020.06.01 |