149 lines
3.8 KiB
TypeScript
149 lines
3.8 KiB
TypeScript
|
|
const fs = require('fs');
|
||
|
|
|
||
|
|
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8').split("\n");
|
||
|
|
|
||
|
|
interface Coord {
|
||
|
|
x: number,
|
||
|
|
y: number,
|
||
|
|
};
|
||
|
|
|
||
|
|
enum Dir {
|
||
|
|
Up,
|
||
|
|
Right,
|
||
|
|
Down,
|
||
|
|
Left,
|
||
|
|
};
|
||
|
|
|
||
|
|
const map: Array<Array<string>> = [];
|
||
|
|
|
||
|
|
const width = 71;
|
||
|
|
const height = 71;
|
||
|
|
|
||
|
|
for (let y = 0; y < height; y++) {
|
||
|
|
if (!map[y]) {
|
||
|
|
map[y] = [];
|
||
|
|
}
|
||
|
|
for (let x = 0; x < width; x++) {
|
||
|
|
map[y][x] = '.';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for (let i = 0; i < 1024; i++) {
|
||
|
|
const [x, y] = input[i].split(',').map((st: string) => parseInt(st));
|
||
|
|
map[y][x] = '#'
|
||
|
|
}
|
||
|
|
|
||
|
|
function get(pos: Coord): string {
|
||
|
|
if (map[pos.y] && map[pos.y][pos.x]) {
|
||
|
|
return map[pos.y][pos.x];
|
||
|
|
}
|
||
|
|
return '#';
|
||
|
|
}
|
||
|
|
|
||
|
|
function set(pos: Coord, val: string): void {
|
||
|
|
map[pos.y][pos.x] = val;
|
||
|
|
}
|
||
|
|
|
||
|
|
function nextDir(dir: Dir): Dir {
|
||
|
|
const directions = [Dir.Up, Dir.Right, Dir.Down, Dir.Left];
|
||
|
|
const i = (directions.indexOf(dir) + 1) % directions.length;
|
||
|
|
return directions[i];
|
||
|
|
}
|
||
|
|
function prevDir(dir: Dir): Dir {
|
||
|
|
const directions = [Dir.Up, Dir.Right, Dir.Down, Dir.Left];
|
||
|
|
const i = directions.indexOf(dir) - 1;
|
||
|
|
if (i < 0) {
|
||
|
|
return directions[directions.length - 1];
|
||
|
|
}
|
||
|
|
return directions[i];
|
||
|
|
}
|
||
|
|
|
||
|
|
function printMap() {
|
||
|
|
const mapClone = map.slice().map((row: Array<string>) => row.slice());
|
||
|
|
console.log(mapClone.map((row: Array<string>) => row.join('')).join("\n"));
|
||
|
|
}
|
||
|
|
|
||
|
|
function nextCoord(pos: Coord, direction: Dir): Coord {
|
||
|
|
return direction === Dir.Up ? { x: pos.x, y: pos.y - 1 }
|
||
|
|
: (direction === Dir.Right ? { x: pos.x + 1, y: pos.y }
|
||
|
|
: (direction === Dir.Down ? { x: pos.x, y: pos.y + 1 } : { x: pos.x - 1, y: pos.y })
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
function isDeadEnd(pos: Coord): boolean {
|
||
|
|
if ((pos.x === 0 && pos.y === 0) || (pos.x === width - 1 && pos.y === width - 1)) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
const adjs = [Dir.Up, Dir.Right, Dir.Down, Dir.Left].map((dir) => get(nextCoord(pos, dir))).join('');
|
||
|
|
return adjs === '###.'
|
||
|
|
|| adjs === '##.#'
|
||
|
|
|| adjs === '#.##'
|
||
|
|
|| adjs === '.###';
|
||
|
|
}
|
||
|
|
|
||
|
|
function fillDeadEnd(pos: Coord): void {
|
||
|
|
set(pos, '#')
|
||
|
|
for (let dir of [Dir.Up, Dir.Right, Dir.Down, Dir.Left]) {
|
||
|
|
const next = nextCoord(pos, dir);
|
||
|
|
if (get(next) === '.') {
|
||
|
|
if (isDeadEnd(next)) {
|
||
|
|
fillDeadEnd(next);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
printMap();
|
||
|
|
console.log("\n");
|
||
|
|
|
||
|
|
for (let y = 0; y < height; y++) {
|
||
|
|
for (let x = 0; x < width; x++) {
|
||
|
|
const pos = { x, y };
|
||
|
|
const char = get(pos);
|
||
|
|
if (char !== '.') {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (isDeadEnd(pos)) {
|
||
|
|
fillDeadEnd(pos);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
printMap();
|
||
|
|
|
||
|
|
//let fastest: number|null = null;
|
||
|
|
//
|
||
|
|
//const scoreCache: { [key: string]: [number, Coord, Dir] } = {};
|
||
|
|
//
|
||
|
|
//const branchCache: { [key: string]: number } = {};
|
||
|
|
//
|
||
|
|
//const scores: Array<number> = [];
|
||
|
|
//
|
||
|
|
//function getScoresAfterPosition(pos: Coord, dir: Dir, path: Array<string> = []): void {
|
||
|
|
// if (fastest !== null && path.length >= fastest) {
|
||
|
|
// return;
|
||
|
|
// }
|
||
|
|
// [dir, nextDir(dir), prevDir(dir)].forEach((newDir, i) => {
|
||
|
|
// const next = nextCoord(pos, newDir);
|
||
|
|
// const nextStr = `${next.x},${next.y}`;
|
||
|
|
// if (!path.includes(nextStr)) {
|
||
|
|
// if (next.x === width - 1 && next.y === height - 1) {
|
||
|
|
// if (fastest === null || path.length < fastest) {
|
||
|
|
// fastest = path.length;
|
||
|
|
// }
|
||
|
|
// scores.push(path.length);
|
||
|
|
// return;
|
||
|
|
// } else if (next.x >= 0 && next. x < width && next.y >= 0 && next.y < height && get(next) === '.') {
|
||
|
|
// getScoresAfterPosition(next, newDir, [...path, nextStr]);
|
||
|
|
// }
|
||
|
|
// }
|
||
|
|
// });
|
||
|
|
//
|
||
|
|
// return;
|
||
|
|
//}
|
||
|
|
//
|
||
|
|
//getScoresAfterPosition({ x: 0, y: 0 }, Dir.Up, ['0,0']);
|
||
|
|
//
|
||
|
|
//console.log(scores);
|
||
|
|
//const fastestScore = Math.min(...scores);
|
||
|
|
//
|