diff --git "a/chw/3week/\354\227\260\352\265\254\354\206\214.js" "b/chw/3week/\354\227\260\352\265\254\354\206\214.js" new file mode 100644 index 0000000..4331a2b --- /dev/null +++ "b/chw/3week/\354\227\260\352\265\254\354\206\214.js" @@ -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; +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); + 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; +}; diff --git "a/chw/3week/\355\224\204\353\240\214\354\246\210 \353\270\224\353\241\235.js" "b/chw/3week/\355\224\204\353\240\214\354\246\210 \353\270\224\353\241\235.js" new file mode 100644 index 0000000..ac661a2 --- /dev/null +++ "b/chw/3week/\355\224\204\353\240\214\354\246\210 \353\270\224\353\241\235.js" @@ -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)) + ); +}; + +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) => { + 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); + } +}