namespace AdventOfCode2019_20_2 { const DAY = 20; const PROBLEM = 2; type Point = [number, number]; export async function run() { let input = await AdventOfCode.getInput(DAY); if (input == null) return; AdventOfCode.setIntermedOutputSize("0.35vw"); let grid = input .split(new RegExp('\r?\n')) .filter(p => p.trim().length > 0) .map(p => p.split('').map(q => q) ); const width = grid[0].length; const height = grid.length; let tunnels: {[_:string]: [Point, Point]} = {}; let tunnelsList: {[_:number]: [boolean, Point]} = {}; let entry: Point = [0, 0]; let exit: Point = [0, 0]; for (let y=1; y3 && y>3 && x " + point_to_str(tunnels[key][1])); } else { if (isinner) tunnels[key] = [pos, [-1, -1]]; else tunnels[key] = [[-1, -1], pos]; } } } for (let y=0; y dqueue.push([0, 0, entry]); let last_dist = -1; while (dqueue.length>0) { const [dist, depth, pt] = dqueue.shift()!; const [ptx, pty] = pt; let ptid2 = id2(pt, depth); let ptid1 = id(pt); if (ptid2 in distmap && distmap[ptid2] <= dist) continue; if (dist !== last_dist) { await AdventOfCode.outputIntermed(toStr2(grid, dqueue, tunnelsList)+"\n\n" + dist); last_dist = dist; } if (depth === 0 && ptx === exit[0] && pty === exit[1]) { AdventOfCode.output(DAY, PROBLEM, dist.toString()); await AdventOfCode.outputIntermed(toStr(grid)); return; } distmap[ptid2] = dist; if (grid[pty-1][ptx] === '.') dqueue.push([ dist+1, depth, [ptx, pty-1] ]); if (grid[pty][ptx+1] === '.') dqueue.push([ dist+1, depth, [ptx+1, pty] ]); if (grid[pty+1][ptx] === '.') dqueue.push([ dist+1, depth, [ptx, pty+1] ]); if (grid[pty][ptx-1] === '.') dqueue.push([ dist+1, depth, [ptx-1, pty] ]); if (ptid1 in tunnelsList) { const [tunnel_dir, tunnel_pos] = tunnelsList[ptid1]; if (depth ===0 && !tunnel_dir) { /* wall */ } else dqueue.push([dist+1, depth + (tunnel_dir ? 1 : -1), tunnel_pos]); } } } function id (p: Point) { return p[1]*10000+p[0]; } function id2(p: Point, d: number) { return p[1]*1000000+1000*p[0]+d; } function isUpperChar(c: string): boolean { return c.charCodeAt(0) >= "A".charCodeAt(0) && c.charCodeAt(0) <= "Z".charCodeAt(0); } function toStr(grid: string[][]): string { return grid.map(p => p.join("") ).join("\n"); } function toStr2(grid: string[][], highlights: [any, any, Point][], tunnels: {[_:number]: [any, Point]}): string { const width = grid[0].length; const height = grid.length; let str = ""; for (let y=0; y p[2][0] === x && p[2][1] === y )) str += "O"; else if (id([x,y]) in tunnels) str += "@"; else str += grid[y][x]; } str += "\n"; } return str } function point_to_str (p: Point) { return `[${p[0]}|${p[1]}]`; } }