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
Empty file.
112 changes: 112 additions & 0 deletions jeongdopark/230926/오목.js
Original file line number Diff line number Diff line change
@@ -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);
}
83 changes: 83 additions & 0 deletions jeongdopark/230926/파이프옮기기1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
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_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 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;
}

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);
14 changes: 7 additions & 7 deletions jeongdopark/example.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
6 4
0100
1110
1000
0000
0111
0000
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 0
158 changes: 60 additions & 98 deletions jeongdopark/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,116 +5,78 @@ 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;
}
}
// 현재 파이프의 놓인 방향을 파악
// 가로, 세로, 대각선
// 각 놓인 상태에 따라서 다음으로 진행할 수 있는 상태가 제한된다.

const [N, M] = input[count++].split(" ").map(Number);
let graph = [];
// 가장 처음 파이프의 위치는 (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(""));
graph.push(input[count++].split(" ").map(Number));
}

let visit = Array.from({ length: N }, () =>
Array.from({ length: M }, () => [0, 0])
);
const direction = [
// 가로
[
[0, 1],
[1, 1],
],
//세로
[
[1, 0],
[1, 1],
],
// 대각선
[
[0, 1],
[1, 0],
[1, 1],
],
];

const BFS = (y, x) => {
const dy = [-1, 1, 0, 0];
const dx = [0, 0, -1, 1];
const DFS = (y, x, dir) => {
if (graph[N - 1][N - 1] === 1) return;
// 도착지일 경우
if (y === N - 1 && x === N - 1) {
answer += 1;
return;
}

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;
// 오른쪽 이동
if (dir === 0 || dir === 2) {
if (x + 1 < N) {
if (graph[y][x + 1] === 0) {
DFS(y, x + 1, 0);
}
}
for (let i = 0; i < 4; i++) {
const next_y = crnt_y + dy[i];
const next_x = crnt_x + dx[i];
}

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;
// 아래로 이동
if (dir === 1 || dir === 2) {
if (y + 1 < N) {
if (graph[y + 1][x] === 0) {
DFS(y + 1, x, 1);
}
}
}

// 부술 기회가 없는 상태일 경우
} 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;
}
// 벽이면서 부술 기회가 있는 경우
} 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;
}
// 대각선 이동
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);
}
}
}
};

BFS(0, 0);
if (answer === 0) {
console.log(-1);
} else {
console.log(answer);
}
DFS(0, 1, 0);
console.log(answer);
Loading