function parse(input) {
const toId = (r, c) => `${r},${c}`;
const fromId = (id) => id.split(",").map(Number);
const g = new Graph();
const grid = input.split("\n").map((row) => row.split(""));
const [nRows, nCols] = [grid.length, grid[0].length];
let start;
for (let row = 0; row < nRows; row++) {
for (let col = 0; col < nCols; col++) {
const cellType = grid[row][col];
if (cellType in directions) {
directions[cellType].forEach(([dr, dc]) => {
const [r2, c2] = [row + dr, col + dc];
if (r2 >= 0 && r2 < nRows && c2 >= 0 && c2 < nCols) {
g.addEdge(toId(row, col), toId(r2, c2));
}
});
} else if (cellType === "S") {
start = toId(row, col);
}
}
}
const determineStartPipeType = (grid, [r0, c0], [r1, c1], [r2, c2]) => {
const isRowGreater = Math.max(r1, r2) > r0;
const isColGreater = Math.max(c1, c2) > c0;
const isColLesser = Math.min(c1, c2) < c0;
if (isRowGreater) {
return isColGreater ? "F" : isColLesser ? "7" : "|";
}
if (Math.min(r1, r2) < r0) {
return isColGreater ? "L" : "J";
}
return "-";
};
const [n1, n2] = g.inNodes(start);
g.addEdge(start, n1);
g.addEdge(start, n2);
grid[fromId(start)[0]][fromId(start)[1]] = determineStartPipeType(
grid,
fromId(start),
fromId(n1),
fromId(n2)
);
return { start, graph: g, grid };
}