Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions chw/3week/연구소.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
const readline = require("readline");

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

const input = [];

rl.on("line", (line) => {
input.push(line);
}).on("close", function () {
const [row, col] = input
.shift()
.split(" ")
.map((el) => Number(el));

const graph = input.map((line) => line.split(" ").map((num) => Number(num)));
const answer = solution(graph, row, col);
console.log(answer);
process.exit();
});

const VIRUS = 2;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 매직넘버를 처리할 수 있었네요... 배워갑니다..👍

const WALL = 1;
const PATH = 0;
const DIRESCTIONS = [
[-1, 0],
[0, 1],
[1, 0],
[0, -1],
];

function findTargetPositions(graph, target) {
const targetPositions = graph.reduce((accVirus, row, i) => {
const virusInRow = row
.map((cell, j) => cell === target && [i, j])
.filter((value) => !!value);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자바스크립트에서는 이런식으로 stream처럼 사용하면 안느린가요??
자바 코테에서는 이렇게 사용하면 느려서 시간초과가 되는 경우가 꽤 있어서 궁금했습니다.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아직 속도에 대한 고민은 해보지 않았지만, 지연평가를 사용해서 속도를 충분히 개선시킬 수 있다고 합니다. 아직, 지연평가에 대해선 공부해보지는 않았는데 메서드 체이닝으로 인해서 시간초과가 발생 한다면 지연 평가를 적용해볼까 합니다 :)

return [...accVirus, ...virusInRow];
}, []);

return targetPositions;
}

const countSafezone = (graph) => {
const safezone = graph.reduce((accSafezone, row, i) => {
const safezoneInrow = row
.map((cell, j) => cell === PATH && [i, j])
.filter((value) => !!value).length;
return accSafezone + safezoneInrow;
}, 0);

return safezone;
};

const isPositionsInLab = (nx, ny, row, col) => {
return nx >= 0 && nx < row && ny >= 0 && ny < col;
};

const polluteLab = (graph, row, col, virus) => {
while (virus.length > 0) {
const [x, y] = virus.shift();
DIRESCTIONS.forEach((dir) => {
const [dx, dy] = dir;
const nx = x + dx;
const ny = y + dy;

if (isPositionsInLab(nx, ny, row, col) && graph[nx][ny] === PATH) {
graph[nx][ny] = VIRUS;
virus.push([nx, ny]);
}
});
}
};

const solution = (graph, row, col) => {
const virusPositions = findTargetPositions(graph, VIRUS);
const pathPositions = findTargetPositions(graph, PATH);

let answer = -Infinity;

for (let i = 0; i < pathPositions.length - 2; i += 1) {
for (let j = i + 1; j < pathPositions.length - 1; j += 1) {
for (let k = j + 1; k < pathPositions.length; k += 1) {
const copyGraph = graph.map((row) => [...row]);
const addWallPositions = [
pathPositions[i],
pathPositions[j],
pathPositions[k],
];

addWallPositions.forEach((addWall) => {
const [x, y] = addWall;
copyGraph[x][y] = WALL;
});

polluteLab(copyGraph, row, col, [...virusPositions]);
const safezone = countSafezone(copyGraph);
answer = Math.max(answer, safezone);
}
}
}

return answer;
};
84 changes: 84 additions & 0 deletions chw/3week/프렌즈 블록.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const DIRECTIONS = [
[0, 1],
[1, 1],
[1, 0],
];

const DESTROYED_MARK = "-";

const getUniquePositions = (arr) => {
return [...new Set(arr.join("|").split("|"))].map((v) =>
v.split(",").map((v) => Number(v))
);
};
Comment on lines +9 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set 없이 중복제거 해보시는건 어떤가요!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생각해보니 map메서드를 활용하면 Set을 사용하지 않고도 충분히 중복제거를 할 수 있겠네요. map으로도 구현해보고 둘의 차이를 정리해 봐야겠습니다!


const countDestructedBlocks = (board) => {
const destructedBlocks = board.reduce((acc, row, i) => {
const destructedBlocksInRow = row
.map((col, j) => col === DESTROYED_MARK && [i, j])
.filter((value) => !!value);

return acc + destructedBlocksInRow.length;
}, 0);

return destructedBlocks;
};

const changePositions = (row, col, board, positions) => {
const changeBlocks = [];

for (let j = 0; j < col; j++) {
for (let i = row - 1; i >= 0; i -= 1) {
if (positions.some((pos) => i === pos[0] && j === pos[1])) {
continue;
}
changeBlocks.push(board[i][j]);
}

while (changeBlocks.length < row) {
changeBlocks.push(DESTROYED_MARK);
}

for (let i = 0; i < row; i += 1) {
board[i][j] = changeBlocks.pop();
}
}
};

const checkDestructibleBlocks = (positions, board, targetPosition) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

같은 블록인지 확인하고 배열에 추가하는 코드를 함수로 빼고 배열 메소드를 사용하니 깔끔하고 잘 읽히는 것 같습니다! positions.push(...destoryedPositions) 이렇게 배열에 추가하는 방법도 배워갑니다!

const [x, y] = targetPosition;

if (
DIRECTIONS.every((dir) => {
const [dx, dy] = dir;
return board[x + dx] && board[x + dx][y + dy] === board[x][y];
})
) {
const destoryedPositions = [
...DIRECTIONS.map((dir) => [x + dir[0], y + dir[1]]),
[x, y],
];
positions.push(...destoryedPositions);
}
};

function solution(row, col, board) {
const gameBoard = board.map((row) => row.split(""));

while (true) {
const positions = [];
gameBoard.forEach((row, i) => {
row.forEach((col, j) => {
if (col === DESTROYED_MARK) return;
checkDestructibleBlocks(positions, gameBoard, [i, j]);
});
});

if (!positions.length) {
return countDestructedBlocks(gameBoard);
}

const uniquePositions = getUniquePositions(positions);
changePositions(row, col, gameBoard, uniquePositions);
}
}