From 0bb168f9f0134cb97110f9a240712d62ac4224ed Mon Sep 17 00:00:00 2001 From: Xeraph Date: Mon, 25 Sep 2023 22:48:48 +0900 Subject: [PATCH 1/4] 9/26 --- ...30\353\212\224\355\212\270\353\237\255.js" | 0 .../230926/\354\230\244\353\252\251.js" | 112 +++++++++++ ...4\354\230\256\352\270\260\352\270\2601.js" | 148 ++++++++++++++ jeongdopark/example.txt | 26 ++- jeongdopark/index.js | 183 ++++++++---------- jeongdopark/test.js | 68 +++---- 6 files changed, 400 insertions(+), 137 deletions(-) create mode 100644 "jeongdopark/230926/\353\213\244\353\246\254\353\245\274\354\247\200\353\202\230\353\212\224\355\212\270\353\237\255.js" create mode 100644 "jeongdopark/230926/\354\230\244\353\252\251.js" create mode 100644 "jeongdopark/230926/\355\214\214\354\235\264\355\224\204\354\230\256\352\270\260\352\270\2601.js" diff --git "a/jeongdopark/230926/\353\213\244\353\246\254\353\245\274\354\247\200\353\202\230\353\212\224\355\212\270\353\237\255.js" "b/jeongdopark/230926/\353\213\244\353\246\254\353\245\274\354\247\200\353\202\230\353\212\224\355\212\270\353\237\255.js" new file mode 100644 index 0000000..e69de29 diff --git "a/jeongdopark/230926/\354\230\244\353\252\251.js" "b/jeongdopark/230926/\354\230\244\353\252\251.js" new file mode 100644 index 0000000..63b4e4b --- /dev/null +++ "b/jeongdopark/230926/\354\230\244\353\252\251.js" @@ -0,0 +1,112 @@ +let input = require("fs") + .readFileSync(__dirname + "/example.txt") + .toString() + .trim() + .split("\n"); +let count = 0; + +// 검은 바둑알 1 +// 흰 바둑알 2 +// 빈칸 0 +// 빈칸이 아닐 경우 8개의 방향을 탐색한다. + +const dy = [-1, -1, -1, 0, 0, 1, 1, 1]; +const dx = [-1, 0, 1, -1, 1, -1, 0, 1]; +const visited = Array.from({ length: 19 }, () => + Array(19).fill(Array(8).fill(false)) +); + +const graph = []; + +for (let i = 0; i < 19; i++) { + graph.push(input[count++].split(" ").map(Number)); +} + +// 탐색 함수 인자로 (현재 위치, 탐색 방향, 바둑돌 색상) +const search = (y, x, dir, target) => { + console.log(y, x, dir, target); + visited[y][x][dir] = true; + let count = 1; + let crnt_y = y; + let crnt_x = x; + const arr = [[y, x]]; + while (true) { + const next_y = crnt_y + dy[dir]; + const next_x = crnt_x + dx[dir]; + console.log(y, x, next_y, next_x); + // 구간 유효성 검사 + if (next_y >= 0 && next_y < 19 && next_x >= 0 && next_x < 19) { + // 연속적으로 같은 색의 바둑돌인지 검사 + if (graph[next_y][next_x] === target) { + console.log(y, x, next_y, next_x); + console.log(visited[next_y][next_x][dir]); + if (visited[next_y][next_x][dir] === false) { + console.log(y, x, next_y, next_x); + visited[next_y][next_x][dir] = true; + arr.push([next_y, next_x]); + count += 1; + // 5목을 넘어갈 경우 + if (count >= 6) return [false]; + crnt_y = next_y; + crnt_x = next_x; + // 다음 칸이 같은 색의 바둑돌이 아닐 경우 + } else { + break; + } + } else { + break; + } + } else { + break; + } + } + // 오목일 경우 + console.log(count); + if (count === 5) return [true, arr]; + else return [false]; +}; + +let answer = []; +// 오목판 순회 +const solution = () => { + for (let i = 0; i < 19; i++) { + for (let k = 0; k < 19; k++) { + if (graph[i][k] !== 0) { + for (let j = 0; j < 8; j++) { + if (visited[i][k][j] === false) { + const result = search(i, k, j, graph[i][k]); + + if (result[0]) { + const temp_arr = result[1]; + temp_arr.sort((a, b) => { + // 두번째 요소 비교 + if (a[1] < b[1]) { + return -1; + } else if (a[1] > b[1]) { + return 1; + } else { + // 두번째 요소가 같을 경우 첫번째 요소로 비교 + return a[0] - b[0]; + } + }); + answer.push(graph[i][k], [ + temp_arr[0][0] + 1, + temp_arr[0][1] + 1, + ]); + return; + } + } + } + } + } + } +}; + +solution(); + +if (answer.length > 0) { + console.log(answer[0]); + console.log(answer[1].join(" ")); +} else { + console.log(0); +} diff --git "a/jeongdopark/230926/\355\214\214\354\235\264\355\224\204\354\230\256\352\270\260\352\270\2601.js" "b/jeongdopark/230926/\355\214\214\354\235\264\355\224\204\354\230\256\352\270\260\352\270\2601.js" new file mode 100644 index 0000000..fccc462 --- /dev/null +++ "b/jeongdopark/230926/\355\214\214\354\235\264\355\224\204\354\230\256\352\270\260\352\270\2601.js" @@ -0,0 +1,148 @@ +class Node { + constructor(start, end) { + this.start = start; + this.end = end; + this.next = null; + } +} + +class Queue { + constructor() { + this.head = null; + this.tail = null; + this.size = 0; + } + + push(start, end) { + let node = new Node(start, end); + if (this.size === 0) { + this.head = node; + } else { + this.tail.next = node; + } + this.tail = node; + this.size++; + } + + shift() { + let temp = this.head; + if (this.size === 0) { + this.head = null; + this.tail = null; + } else { + this.head = this.head.next; + } + this.size--; + return temp; + } +} + +let input = require("fs") + .readFileSync(__dirname + "/example.txt") + .toString() + .trim() + .split("\n"); +let count = 0; + +// 현재 파이프의 놓인 방향을 파악 +// 가로, 세로, 대각선 +// 각 놓인 상태에 따라서 다음으로 진행할 수 있는 상태가 제한된다. + +// 가장 처음 파이프의 위치는 (0,0), (0,1) +let answer = 0; +const N = Number(input[count++]); +const graph = []; + +for (let i = 0; i < N; i++) { + graph.push(input[count++].split(" ").map(Number)); +} + +const direction = [ + // 가로 + [ + [0, 1], + [1, 1], + ], + //세로 + [ + [1, 0], + [1, 1], + ], + // 대각선 + [ + [0, 1], + [1, 0], + [1, 1], + ], +]; + +// 현재 파이프의 방향을 반환하는 함수 +const pipe_status = (start, end) => { + const [start_y, start_x] = start; + const [end_y, end_x] = end; + // 가로일 경우 + if (start_y === end_y && start_x === end_x - 1) { + return 0; + } + // 세로일 경우 + if (start_y === end_y - 1 && start_x === end_x) { + return 1; + } + // 대각선일 경우 + if (start_y === end_y - 1 && start_x === end_x - 1) { + return 2; + } +}; +if (graph[N - 1][N - 1] === 1) { + answer = 0; +} else { + const BFS = () => { + const start = [0, 0]; // 파이프의 시작 지점 + const end = [0, 1]; // 파이프의 끝 지점 + const queue = new Queue(); + // const queue = [[start, end]]; + queue.push(start, end); + // console.log(queue); + while (queue.size > 0) { + const crnt = queue.shift(); + const crnt_start = crnt.start; + const crnt_end = crnt.end; + + const crnt_direction = pipe_status(crnt_start, crnt_end); + for (let i = 0; i < direction[crnt_direction].length; i++) { + const dy = direction[crnt_direction][i][0]; + const dx = direction[crnt_direction][i][1]; + const next_y = crnt_end[0] + dy; + const next_x = crnt_end[1] + dx; + + // 격자판 내부인지 확인 + if (next_y >= 0 && next_y < N && next_x >= 0 && next_x < N) { + // 대각선 이동일 경우, 3칸을 확인해야한다. 3칸이 빈칸이어야함. + if (dy === 1 && dx === 1) { + if ( + graph[crnt_end[0] + 1][crnt_end[1]] === 0 && + graph[crnt_end[0]][crnt_end[1] + 1] === 0 && + graph[crnt_end[0] + 1][crnt_end[1] + 1] === 0 + ) { + if (next_y === N - 1 && next_x === N - 1) { + answer += 1; + } + queue.push(crnt_end, [next_y, next_x]); + } + // 대각선 이동이 아닐 경우 + } else { + if (graph[next_y][next_x] === 0) { + if (next_y === N - 1 && next_x === N - 1) { + answer += 1; + } + queue.push(crnt_end, [next_y, next_x]); + } + } + } + } + } + }; + BFS(); +} + +console.log(answer); diff --git a/jeongdopark/example.txt b/jeongdopark/example.txt index 3e77eae..df99384 100644 --- a/jeongdopark/example.txt +++ b/jeongdopark/example.txt @@ -1,7 +1,19 @@ -6 4 -0100 -1110 -1000 -0000 -0111 -0000 \ No newline at end of file +1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \ No newline at end of file diff --git a/jeongdopark/index.js b/jeongdopark/index.js index a7769f4..412e023 100644 --- a/jeongdopark/index.js +++ b/jeongdopark/index.js @@ -5,116 +5,105 @@ let input = require("fs") .split("\n"); let count = 0; -class Node { - constructor(y, x, cnt, isBreak) { - this.x = x; - this.y = y; - this.isBreak = isBreak; - this.cnt = cnt; - this.next = null; - } -} - -class Queue { - constructor() { - this.head = null; - this.tail = null; - this.size = 0; - } - push(y, x, cnt, isBreak) { - let node = new Node(y, x, cnt, isBreak); - if (this.size === 0) { - this.head = node; - } else { - this.tail.next = node; - } - this.tail = node; - this.size++; - } - shift() { - let temp = this.head; - if (this.size === 0) { - this.head = null; - this.tail = null; - } else { - this.head = this.head.next; - } - this.size--; - return temp; - } - get length() { - return this.size; - } -} +// 검은 바둑알 1 +// 흰 바둑알 2 +// 빈칸 0 +// 빈칸이 아닐 경우 8개의 방향을 탐색한다. -const [N, M] = input[count++].split(" ").map(Number); -let graph = []; -let answer = 0; -for (let i = 0; i < N; i++) { - graph.push(input[count++].split("")); -} - -let visit = Array.from({ length: N }, () => - Array.from({ length: M }, () => [0, 0]) +const dy = [-1, -1, -1, 0, 0, 1, 1, 1]; +const dx = [-1, 0, 1, -1, 1, -1, 0, 1]; +const visited = Array.from({ length: 19 }, () => + Array(19).fill(Array(8).fill(false)) ); +console.log(visited[0][0]); +console.log(visited[0]); + +const graph = []; -const BFS = (y, x) => { - const dy = [-1, 1, 0, 0]; - const dx = [0, 0, -1, 1]; +for (let i = 0; i < 19; i++) { + graph.push(input[count++].split(" ").map(Number)); +} - let queue = new Queue(); - // ( y, x, 이동 카운트, 벽 부술 기회 ) - queue.push(0, 0, 1, 1); - visit[0][0][0] = 1; - visit[0][0][1] = 1; - while (queue.length > 0) { - console.log(visit); - let q = queue.shift(); - const [crnt_y, crnt_x, move_count, break_count] = [ - q.y, - q.x, - q.cnt, - q.isBreak, - ]; - if (crnt_y === N - 1 && crnt_x === M - 1) { - answer = move_count; - return; +// 탐색 함수 인자로 (현재 위치, 탐색 방향, 바둑돌 색상) +const search = (y, x, dir, target) => { + visited[y][x][dir] = true; + let count = 1; + let crnt_y = y; + let crnt_x = x; + const arr = [[y, x]]; + while (true) { + const next_y = crnt_y + dy[dir]; + const next_x = crnt_x + dx[dir]; + console.log(y, x, next_y, next_x); + // 구간 유효성 검사 + if (next_y >= 0 && next_y < 19 && next_x >= 0 && next_x < 19) { + // 연속적으로 같은 색의 바둑돌인지 검사 + if (graph[next_y][next_x] === target) { + if (visited[next_y][next_x][dir] === false) { + visited[next_y][next_x][dir] = true; + arr.push([next_y, next_x]); + count += 1; + // 5목을 넘어갈 경우 + if (count >= 6) return [false]; + crnt_y = next_y; + crnt_x = next_x; + // 다음 칸이 같은 색의 바둑돌이 아닐 경우 + } else { + break; + } + } else { + break; + } + } else { + break; } - for (let i = 0; i < 4; i++) { - const next_y = crnt_y + dy[i]; - const next_x = crnt_x + dx[i]; + } + // 오목일 경우 + if (count === 5) return [true, arr]; + else return [false]; +}; - if (next_y >= 0 && next_y < N && next_x >= 0 && next_x < M) { - if (graph[next_y][next_x] === "0") { - // 다음 칸이 1이 아니고 방문한적 없는 칸일경우 - if (next_y === N - 1 && next_x === M - 1) { - // 다음 칸이 목적지일 경우 - answer = move_count + 1; - return; - } - // 부술 기회가 있는 상태일 경우 - if (break_count === 1 && visit[next_y][next_x][0] === 0) { - queue.push(next_y, next_x, move_count + 1, break_count); - visit[next_y][next_x][0] = move_count + 1; +let answer = []; +// 오목판 순회 +const solution = () => { + for (let i = 0; i < 19; i++) { + for (let k = 0; k < 19; k++) { + if (graph[i][k] !== 0) { + for (let j = 0; j < 8; j++) { + if (visited[i][k][j] === false) { + const result = search(i, k, j, graph[i][k]); - // 부술 기회가 없는 상태일 경우 - } else if (break_count === 0 && visit[next_y][next_x][1] === 0) { - queue.push(next_y, next_x, move_count + 1, break_count); - visit[next_y][next_x][1] = move_count + 1; + if (result[0]) { + const temp_arr = result[1]; + temp_arr.sort((a, b) => { + // 두번째 요소 비교 + if (a[1] < b[1]) { + return -1; + } else if (a[1] > b[1]) { + return 1; + } else { + // 두번째 요소가 같을 경우 첫번째 요소로 비교 + return a[0] - b[0]; + } + }); + answer.push(graph[i][k], [ + temp_arr[0][0] + 1, + temp_arr[0][1] + 1, + ]); + return; + } } - // 벽이면서 부술 기회가 있는 경우 - } else if (graph[next_y][next_x] === "1" && break_count === 1) { - queue.push(next_y, next_x, move_count + 1, break_count - 1); - visit[next_y][next_x][0] = move_count + 1; } } } } }; -BFS(0, 0); -if (answer === 0) { - console.log(-1); +solution(); + +if (answer.length > 0) { + console.log(answer[0]); + console.log(answer[1].join(" ")); } else { - console.log(answer); + console.log(0); } diff --git a/jeongdopark/test.js b/jeongdopark/test.js index 37930d0..c7b9dce 100644 --- a/jeongdopark/test.js +++ b/jeongdopark/test.js @@ -1,39 +1,41 @@ -// 2중 For문 10^6 * 10^6 시간 복잡도 너무 크다 -// 1. Stack 자료구조 -// 상승세일 때 stack에 담는다. -// 하락세일 경우 stack 맨 위에 있는 요소와 비교하면서, 맨 위 요소가 더 작을 경우 pop +// 모든 트럭 다리를 건너려면 몇 초가 걸리는지 +// 다리 : 최대 제한 트럭 개수 & 무게 제한 +// 다리에 완전히 오르지 않은 트럭 무게는 무시한다. -const solution = (prices) => { - const stack = []; - const answer = Array(prices.length).fill(0); - const N = prices.length - 1; - for (let i = 0; i < prices.length; i++) { - // 스택이 비어 있을 경우 - if (stack.length === 0) { - stack.push([prices[i], i]); - } else { - while (stack.length !== 0) { - const top_number = stack[stack.length - 1][0]; - // 스택 가장 위에 있는 숫자보다 현재 숫자가 같거나 클 경우 - if (top_number <= prices[i]) { - stack.push([prices[i], i]); - break; - // 하락세 - } else { - const [price, idx] = stack.pop(); - answer[idx] = i - idx; - if (stack.length === 0) { - stack.push([prices[i], i]); - break; - } - } +// bridge_length : 다리에 올라올 수 있는 트럭 수 +// weight : 다리 무게 제한 +// truck_weights : 트럭 별 무게 +const solution = (bridge_length, weight, truck_weights) => { + var answer = 0; + // 다리 위 트럭 queue + const queue = []; + // 다리 위 총 트럭 무게 + let queue_weight = 0; + + while (truck_weights.length > 0) { + answer += 1; + // 다리 위에 트럭이 있을 경우 + if (queue.length !== 0) { + // 모든 트럭 한칸씩 이동 + for (let i = 0; i < queue.length; i++) { + queue[i][1] += 1; + } + // 가장 앞에 있는 트럭이 다리를 건넜을 경우 + if (queue[0][1] === bridge_length + 1) { + queue_weight -= queue[0][0]; + queue.shift(); } } + // 현재 다리 위 총 트럭 무게 + 들어올 트럭 <= 다리가 견딜 수 있는 무게 + if (queue_weight + truck_weights[0] <= weight) { + // [트럭 무게, 초] + const crnt_truck = [truck_weights[0], 1]; + queue.push(crnt_truck); + queue_weight += crnt_truck[0]; + truck_weights.shift(); + } } - for (let i = 0; i < stack.length; i++) { - answer[stack[i][1]] = N - stack[i][1]; - } - return answer; + return answer + bridge_length; }; -console.log(solution([1, 2, 3, 2, 3])); +console.log(solution(100, 100, [10])); From 81eb8aa6f7261063bcf24de2af68eaefec48ee54 Mon Sep 17 00:00:00 2001 From: Xeraph Date: Tue, 26 Sep 2023 08:50:19 +0900 Subject: [PATCH 2/4] ver2 --- ...4\354\230\256\352\270\260\352\270\2601.js" | 113 +++---------- jeongdopark/example.txt | 26 +-- jeongdopark/index.js | 154 ++++++++---------- 3 files changed, 96 insertions(+), 197 deletions(-) diff --git "a/jeongdopark/230926/\355\214\214\354\235\264\355\224\204\354\230\256\352\270\260\352\270\2601.js" "b/jeongdopark/230926/\355\214\214\354\235\264\355\224\204\354\230\256\352\270\260\352\270\2601.js" index fccc462..638fa3e 100644 --- "a/jeongdopark/230926/\355\214\214\354\235\264\355\224\204\354\230\256\352\270\260\352\270\2601.js" +++ "b/jeongdopark/230926/\355\214\214\354\235\264\355\224\204\354\230\256\352\270\260\352\270\2601.js" @@ -1,42 +1,3 @@ -class Node { - constructor(start, end) { - this.start = start; - this.end = end; - this.next = null; - } -} - -class Queue { - constructor() { - this.head = null; - this.tail = null; - this.size = 0; - } - - push(start, end) { - let node = new Node(start, end); - if (this.size === 0) { - this.head = node; - } else { - this.tail.next = node; - } - this.tail = node; - this.size++; - } - - shift() { - let temp = this.head; - if (this.size === 0) { - this.head = null; - this.tail = null; - } else { - this.head = this.head.next; - } - this.size--; - return temp; - } -} - let input = require("fs") .readFileSync(__dirname + "/example.txt") .toString() @@ -77,7 +38,7 @@ const direction = [ ]; // 현재 파이프의 방향을 반환하는 함수 -const pipe_status = (start, end) => { +const pipe_direction = (start, end) => { const [start_y, start_x] = start; const [end_y, end_x] = end; // 가로일 경우 @@ -93,56 +54,30 @@ const pipe_status = (start, end) => { return 2; } }; -if (graph[N - 1][N - 1] === 1) { - answer = 0; -} else { - const BFS = () => { - const start = [0, 0]; // 파이프의 시작 지점 - const end = [0, 1]; // 파이프의 끝 지점 - const queue = new Queue(); - // const queue = [[start, end]]; - queue.push(start, end); - // console.log(queue); - while (queue.size > 0) { - const crnt = queue.shift(); - const crnt_start = crnt.start; - const crnt_end = crnt.end; - const crnt_direction = pipe_status(crnt_start, crnt_end); - for (let i = 0; i < direction[crnt_direction].length; i++) { - const dy = direction[crnt_direction][i][0]; - const dx = direction[crnt_direction][i][1]; - const next_y = crnt_end[0] + dy; - const next_x = crnt_end[1] + dx; +const DFS = (start, end) => { + const dir = pipe_direction(start, end); + const [end_y, end_x] = end; + // 도착지일 경우 + if (end_y === N - 1 && end_x === N - 1) { + answer += 1; + return; + } + // 범위를 벗어난 경우 return + if (end_y < 0 || end_y >= N || end_x < 0 || end_x >= N) return; + // 벽일 경우 return + if (graph[end_y][end_x] === 1) return; + // 대각선일 경우 3곳을 확인해야한다. + if (dir === 2) { + if (graph[end_y - 1][end_x] === 1 || graph[end_y][end_x - 1] === 1) return; + } - // 격자판 내부인지 확인 - if (next_y >= 0 && next_y < N && next_x >= 0 && next_x < N) { - // 대각선 이동일 경우, 3칸을 확인해야한다. 3칸이 빈칸이어야함. - if (dy === 1 && dx === 1) { - if ( - graph[crnt_end[0] + 1][crnt_end[1]] === 0 && - graph[crnt_end[0]][crnt_end[1] + 1] === 0 && - graph[crnt_end[0] + 1][crnt_end[1] + 1] === 0 - ) { - if (next_y === N - 1 && next_x === N - 1) { - answer += 1; - } - queue.push(crnt_end, [next_y, next_x]); - } - // 대각선 이동이 아닐 경우 - } else { - if (graph[next_y][next_x] === 0) { - if (next_y === N - 1 && next_x === N - 1) { - answer += 1; - } - queue.push(crnt_end, [next_y, next_x]); - } - } - } - } - } - }; - BFS(); -} + for (let i = 0; i < direction[dir].length; i++) { + const end_next_y = end_y + direction[dir][i][0]; + const end_next_x = end_x + direction[dir][i][1]; + DFS(end, [end_next_y, end_next_x]); + } +}; +DFS([0, 0], [0, 1]); console.log(answer); diff --git a/jeongdopark/example.txt b/jeongdopark/example.txt index df99384..25532d3 100644 --- a/jeongdopark/example.txt +++ b/jeongdopark/example.txt @@ -1,19 +1,7 @@ -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \ No newline at end of file +6 +0 0 0 0 0 0 +0 1 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 1 \ No newline at end of file diff --git a/jeongdopark/index.js b/jeongdopark/index.js index 412e023..1310f6a 100644 --- a/jeongdopark/index.js +++ b/jeongdopark/index.js @@ -5,105 +5,81 @@ let input = require("fs") .split("\n"); let count = 0; -// 검은 바둑알 1 -// 흰 바둑알 2 -// 빈칸 0 -// 빈칸이 아닐 경우 8개의 방향을 탐색한다. - -const dy = [-1, -1, -1, 0, 0, 1, 1, 1]; -const dx = [-1, 0, 1, -1, 1, -1, 0, 1]; -const visited = Array.from({ length: 19 }, () => - Array(19).fill(Array(8).fill(false)) -); -console.log(visited[0][0]); -console.log(visited[0]); +// 현재 파이프의 놓인 방향을 파악 +// 가로, 세로, 대각선 +// 각 놓인 상태에 따라서 다음으로 진행할 수 있는 상태가 제한된다. +// 가장 처음 파이프의 위치는 (0,0), (0,1) +let answer = 0; +const N = Number(input[count++]); const graph = []; -for (let i = 0; i < 19; i++) { +for (let i = 0; i < N; i++) { graph.push(input[count++].split(" ").map(Number)); } -// 탐색 함수 인자로 (현재 위치, 탐색 방향, 바둑돌 색상) -const search = (y, x, dir, target) => { - visited[y][x][dir] = true; - let count = 1; - let crnt_y = y; - let crnt_x = x; - const arr = [[y, x]]; - while (true) { - const next_y = crnt_y + dy[dir]; - const next_x = crnt_x + dx[dir]; - console.log(y, x, next_y, next_x); - // 구간 유효성 검사 - if (next_y >= 0 && next_y < 19 && next_x >= 0 && next_x < 19) { - // 연속적으로 같은 색의 바둑돌인지 검사 - if (graph[next_y][next_x] === target) { - if (visited[next_y][next_x][dir] === false) { - visited[next_y][next_x][dir] = true; - arr.push([next_y, next_x]); - count += 1; - // 5목을 넘어갈 경우 - if (count >= 6) return [false]; - crnt_y = next_y; - crnt_x = next_x; - // 다음 칸이 같은 색의 바둑돌이 아닐 경우 - } else { - break; - } - } else { - break; - } - } else { - break; - } +const direction = [ + // 가로 + [ + [0, 1], + [1, 1], + ], + //세로 + [ + [1, 0], + [1, 1], + ], + // 대각선 + [ + [0, 1], + [1, 0], + [1, 1], + ], +]; + +// 현재 파이프의 방향을 반환하는 함수 +const pipe_direction = (start, end) => { + const [start_y, start_x] = start; + const [end_y, end_x] = end; + // 가로일 경우 + if (start_y === end_y && start_x === end_x - 1) { + return 0; + } + // 세로일 경우 + if (start_y === end_y - 1 && start_x === end_x) { + return 1; + } + // 대각선일 경우 + if (start_y === end_y - 1 && start_x === end_x - 1) { + return 2; } - // 오목일 경우 - if (count === 5) return [true, arr]; - else return [false]; }; -let answer = []; -// 오목판 순회 -const solution = () => { - for (let i = 0; i < 19; i++) { - for (let k = 0; k < 19; k++) { - if (graph[i][k] !== 0) { - for (let j = 0; j < 8; j++) { - if (visited[i][k][j] === false) { - const result = search(i, k, j, graph[i][k]); +const DFS = (start, end) => { + if (graph[N - 1][N - 1] === 1) return; + const dir = pipe_direction(start, end); + const [end_y, end_x] = end; + // 도착지일 경우 - if (result[0]) { - const temp_arr = result[1]; - temp_arr.sort((a, b) => { - // 두번째 요소 비교 - if (a[1] < b[1]) { - return -1; - } else if (a[1] > b[1]) { - return 1; - } else { - // 두번째 요소가 같을 경우 첫번째 요소로 비교 - return a[0] - b[0]; - } - }); - answer.push(graph[i][k], [ - temp_arr[0][0] + 1, - temp_arr[0][1] + 1, - ]); - return; - } - } - } - } - } + // 범위를 벗어난 경우 return + if (end_y < 0 || end_y >= N || end_x < 0 || end_x >= N) return; + // 벽일 경우 return + if (graph[end_y][end_x] === 1) return; + // 대각선일 경우 3곳을 확인해야한다. + if (dir === 2) { + if (graph[end_y - 1][end_x] === 1 || graph[end_y][end_x - 1] === 1) return; + } + if (end_y === N - 1 && end_x === N - 1) { + answer += 1; + return; } -}; -solution(); + for (let i = 0; i < direction[dir].length; i++) { + const end_next_y = end_y + direction[dir][i][0]; + const end_next_x = end_x + direction[dir][i][1]; + DFS(end, [end_next_y, end_next_x]); + } +}; -if (answer.length > 0) { - console.log(answer[0]); - console.log(answer[1].join(" ")); -} else { - console.log(0); -} +DFS([0, 0], [0, 1]); +console.log(answer); From 8d18cef3c69e2903404019970ba17fc71d18b1d3 Mon Sep 17 00:00:00 2001 From: Xeraph Date: Tue, 26 Sep 2023 09:23:38 +0900 Subject: [PATCH 3/4] DFS --- jeongdopark/example.txt | 2 +- jeongdopark/index.js | 39 +++++++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/jeongdopark/example.txt b/jeongdopark/example.txt index 25532d3..2e246bf 100644 --- a/jeongdopark/example.txt +++ b/jeongdopark/example.txt @@ -4,4 +4,4 @@ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0 0 0 0 0 1 \ No newline at end of file +0 0 0 0 0 0 \ No newline at end of file diff --git a/jeongdopark/index.js b/jeongdopark/index.js index 1310f6a..abc78be 100644 --- a/jeongdopark/index.js +++ b/jeongdopark/index.js @@ -60,24 +60,39 @@ const DFS = (start, end) => { const dir = pipe_direction(start, end); const [end_y, end_x] = end; // 도착지일 경우 - - // 범위를 벗어난 경우 return - if (end_y < 0 || end_y >= N || end_x < 0 || end_x >= N) return; - // 벽일 경우 return - if (graph[end_y][end_x] === 1) return; - // 대각선일 경우 3곳을 확인해야한다. - if (dir === 2) { - if (graph[end_y - 1][end_x] === 1 || graph[end_y][end_x - 1] === 1) return; - } if (end_y === N - 1 && end_x === N - 1) { answer += 1; return; } for (let i = 0; i < direction[dir].length; i++) { - const end_next_y = end_y + direction[dir][i][0]; - const end_next_x = end_x + direction[dir][i][1]; - DFS(end, [end_next_y, end_next_x]); + const dy = direction[dir][i][0]; + const dx = direction[dir][i][1]; + + const end_next_y = end_y + dy; + const end_next_x = end_x + dx; + + if ( + end_next_y >= 0 && + end_next_y < N && + end_next_x >= 0 && + end_next_x < N + ) { + if (graph[end_next_y][end_next_x] === 0) { + // 대각선 + if (dy === 1 && dx === 1) { + if ( + graph[end_next_y - 1][end_next_x] === 0 && + graph[end_next_y][end_next_x - 1] === 0 + ) { + DFS(end, [end_next_y, end_next_x]); + } + // 대각선 아닌 경우 + } else { + DFS(end, [end_next_y, end_next_x]); + } + } + } } }; From a82edf39af4301e36b904b62c189a04d27bc38b4 Mon Sep 17 00:00:00 2001 From: Xeraph Date: Tue, 26 Sep 2023 09:34:36 +0900 Subject: [PATCH 4/4] DFS answer --- jeongdopark/index.js | 76 +++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 47 deletions(-) diff --git a/jeongdopark/index.js b/jeongdopark/index.js index abc78be..c0c42bf 100644 --- a/jeongdopark/index.js +++ b/jeongdopark/index.js @@ -37,64 +37,46 @@ const direction = [ ], ]; -// 현재 파이프의 방향을 반환하는 함수 -const pipe_direction = (start, end) => { - const [start_y, start_x] = start; - const [end_y, end_x] = end; - // 가로일 경우 - if (start_y === end_y && start_x === end_x - 1) { - return 0; - } - // 세로일 경우 - if (start_y === end_y - 1 && start_x === end_x) { - return 1; - } - // 대각선일 경우 - if (start_y === end_y - 1 && start_x === end_x - 1) { - return 2; - } -}; - -const DFS = (start, end) => { +const DFS = (y, x, dir) => { if (graph[N - 1][N - 1] === 1) return; - const dir = pipe_direction(start, end); - const [end_y, end_x] = end; // 도착지일 경우 - if (end_y === N - 1 && end_x === N - 1) { + if (y === N - 1 && x === N - 1) { answer += 1; return; } - for (let i = 0; i < direction[dir].length; i++) { - const dy = direction[dir][i][0]; - const dx = direction[dir][i][1]; + // 오른쪽 이동 + if (dir === 0 || dir === 2) { + if (x + 1 < N) { + if (graph[y][x + 1] === 0) { + DFS(y, x + 1, 0); + } + } + } - const end_next_y = end_y + dy; - const end_next_x = end_x + dx; + // 아래로 이동 + if (dir === 1 || dir === 2) { + if (y + 1 < N) { + if (graph[y + 1][x] === 0) { + DFS(y + 1, x, 1); + } + } + } - if ( - end_next_y >= 0 && - end_next_y < N && - end_next_x >= 0 && - end_next_x < N - ) { - if (graph[end_next_y][end_next_x] === 0) { - // 대각선 - if (dy === 1 && dx === 1) { - if ( - graph[end_next_y - 1][end_next_x] === 0 && - graph[end_next_y][end_next_x - 1] === 0 - ) { - DFS(end, [end_next_y, end_next_x]); - } - // 대각선 아닌 경우 - } else { - DFS(end, [end_next_y, end_next_x]); - } + // 대각선 이동 + if (dir === 0 || dir === 1 || dir === 2) { + if (y + 1 < N && x + 1 < N) { + // 세곳을 확인해야한다. + if ( + graph[y + 1][x + 1] === 0 && + graph[y + 1][x] === 0 && + graph[y][x + 1] === 0 + ) { + DFS(y + 1, x + 1, 2); } } } }; -DFS([0, 0], [0, 1]); +DFS(0, 1, 0); console.log(answer);