type Direction = "R" | "L" | "U" | "D"; type Instruction = { direction: Direction; steps: number; color: number; } async function readInput(filename: string): Promise { const input = await Deno.readTextFile(filename); const lines = input.split("\n").map(x => x.trim()).filter(x => x.length > 0); return lines.map(line => { const m = /^([RDLU])\s+(\d+)\s+\(#([0-9a-f]+)\)$/.exec(line); if (!m) { throw new Error(`unknown line ${line}`); } return { direction: m[1] as Direction, steps: parseInt(m[2]), color: parseInt(m[3], 16), } }); } const input = await readInput("input.txt"); function calcWidthAndHeight(insts: Instruction[]){ let maxX = 0, maxY = 0; let minX = 0, minY = 0; insts.reduce<[number,number]>(([x,y]: [number, number], b: Instruction) => { maxX = Math.max(maxX, x); maxY = Math.max(maxY, y); minX = Math.min(minX, x); minY = Math.min(minY, y); if (b.direction === "R"){ return [x + b.steps, y]; } if (b.direction === "L"){ return [x - b.steps, y]; } if (b.direction === "U"){ return [x, y - b.steps]; } if (b.direction === "D"){ return [x, y + b.steps]; } throw new Error(`unknown direction ${b.direction}`); }, [0,0] as [number, number]); return { size: [maxX - minX + 1, maxY - minY + 1], initPos: [-minX, -minY] }; } const {size:[width, height], initPos: [initX, initY]} = calcWidthAndHeight(input); console.log((`x: ${width}, y: ${height}`)); function drawMap(instructions: Instruction[], initX: number, initY: number, width: number, height:number){ const map = new Array(height).fill(0).map(()=>new Array(width).fill(".")) as string[][]; let [x, y] = [initX, initY]; instructions.forEach(({direction, steps, color}) => { for (let i = 0; i < steps; i++) { if (direction === "R"){ map[y][x] = "#"//rgb24("#", color); x++; } if (direction === "L"){ map[y][x] = "#"//rgb24("#", color); x--; } if (direction === "U"){ map[y][x] = "#"//rgb24("#", color); y--; } if (direction === "D"){ map[y][x] = "#"//rgb24("#", color); y++; } } }); // fill inner for (let i = 1; i < height - 1; i++) { let isInner = false; let upDetected = false; let downDetected = false; let j = 0; while (j < width - 1) { if (map[i][j] === "#"){ if (map[i - 1][j] === "#"){ upDetected = !upDetected; } if (map[i + 1][j] === "#"){ downDetected = !downDetected; } if (upDetected && downDetected){ isInner = true; } if (!upDetected && !downDetected){ isInner = false; } } if (isInner && map[i][j] === "."){ map[i][j] = "@"; } j++; } } // console.log(map.map(x => x.join("")).join("\n")); return map.map(x => x.join("")).join("\n"); } const map = drawMap(input, initX, initY, width, height); await Deno.writeTextFile("output.txt", map); console.log(map.split("").filter(x => x === "#" || x === "@").length);