aoc-2023/day_10/solve_2.ts

171 lines
3.8 KiB
TypeScript
Raw Normal View History

2024-12-09 22:41:02 +09:00
type Dir = "U" | "D" | "L" | "R"
type PipeType = "." | "|" | "7" | "J" | "F" | "L" | "-" | "S";
type MoveState = {
fromDir: Dir,
curX: number,
curY: number,
}
const transitionTable: Record<Dir, Record<PipeType, Dir | null>> = {
"U": {
"|": "U",
"7": "L",
"F": "R",
".": null,
"J": null,
"L": null,
"-": null,
"S": null
},
"D": {
"|": "D",
"7": null,
"F": null,
".": null,
"J": "L",
"L": "R",
"-": null,
"S": null
},
"L": {
"|": null,
"7": null,
"F": "D",
".": null,
"J": null,
"L": "U",
"-": "L",
"S": null,
},
"R": {
"|": null,
"7": "D",
"F": null,
".": null,
"J": "U",
"L": null,
"-": "R",
"S": null
}
}
function getNextState(pipeMap: PipeType[][], state: MoveState) {
const curPipe = pipeMap[state.curY][state.curX];
const nextDir = transitionTable[state.fromDir][curPipe];
if (nextDir === null) {
return null;
}
switch (nextDir) {
case "U":
state.curY--;
break;
case "D":
state.curY++;
break;
case "L":
state.curX--;
break;
case "R":
state.curX++;
break;
}
state.fromDir = nextDir;
return state;
}
const input = await Deno.readTextFile("input.txt");
const lines = input.split("\n").map(x => x.trim()).filter(x => x.length > 0);
const pipeMap = lines.map(x => {
return x.split("");
}) as PipeType[][];
let startX = 0, startY = 0;
startY = pipeMap.findIndex(pipeLine => {
const xIndex = pipeLine.findIndex(x => x === "S")
if (xIndex !== -1) {
startX = xIndex;
return true;
}
return false;
});
console.log(startX, startY);
const simplePipeMap: string[][] = new Array(pipeMap.length).fill(".").map(_ => new Array(pipeMap[0].length).fill("."));
function iterateStep(pipeMap: PipeType[][],
state: MoveState,
fn: (state: MoveState) => void) {
fn({...state});
while (true) {
const nextState = getNextState(pipeMap,{...state});
if (nextState === null) {
throw new Error("dead end at " + state.curX + "," + state.curY);
}
if (pipeMap[nextState.curY][nextState.curX] === "S") {
return;
}
fn(nextState);
state = nextState;
}
}
const initStates = [
// {
// fromDir: "U",
// curX: startX,
// curY: startY - 1,
// },
// {
// fromDir: "R",
// curX: startX + 1,
// curY: startY,
// },
{
fromDir: "D",
curX: startX,
curY: startY + 1,
},
{
fromDir: "L",
curX: startX - 1,
curY: startY,
}
] as MoveState[];
for (const initState of initStates) {
// const index = initStates.indexOf(initState);
try {
iterateStep(pipeMap, {...initState}, (state) => {
simplePipeMap[state.curY][state.curX] = pipeMap[state.curY][state.curX];
});
}
catch(_) {
console.log("error",initState);
}
}
simplePipeMap[startY][startX] = "7";
// line scan
// When the line intersects the line of the figure, it is a state in which the line enters or exits the figure.
let count = 0;
for(let iy = 0; iy < simplePipeMap.length; iy++){
let isInside = false;
const row = simplePipeMap[iy];
for(let ix = 0; ix < row.length; ix++){
const pipe = row[ix];
if (["|", "J", "L"].includes(pipe)) {
isInside = !isInside;
}
if (pipe === "." && isInside) {
count++;
}
}
// Reset isInner to false for each new row
isInside = false;
}
console.log(count);