-
Notifications
You must be signed in to change notification settings - Fork 2
[최현웅] 3주차 문제 해결 #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[최현웅] 3주차 문제 해결 #13
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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; | ||
| 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); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 자바스크립트에서는 이런식으로 stream처럼 사용하면 안느린가요??
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
| }; | ||
| 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. set 없이 중복제거 해보시는건 어떤가요!
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 생각해보니 |
||
|
|
||
| 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) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이렇게 매직넘버를 처리할 수 있었네요... 배워갑니다..👍