const fs = require('fs'); const input = fs.readFileSync(__dirname + '/input.txt', 'utf8'); interface Coord { x: number, y: number }; interface Plot { x: number, y: number, edges: number, corners: number }; const plots: Array> = input.split("\n").slice(0, -1).map((row: string) => row.split('')); const height = plots.length; const width = plots[0].length; const regions: Array> = []; function getAllAdjacentPlots({ x, y }: Coord) { const letter = plots[y][x]; plots[y][x] = '.' + letter; const plot = { x, y, edges: 0, corners: 0 }; let adj: Array = [plot]; let adjLetters: Array = []; [ { x, y: y - 1 }, { x: x + 1, y: y - 1 }, { x: x + 1, y }, { x: x + 1, y: y + 1 }, { x, y: y + 1 }, { x: x - 1, y: y + 1 }, { x: x - 1, y }, { x: x - 1, y: y - 1 }, ].forEach((adjCoord, i) => { const adjLetter = plots[adjCoord.y] && plots[adjCoord.y][adjCoord.x]; if (i % 2 === 0) { if (adjLetter === letter) { adj = [...adj, ...getAllAdjacentPlots(adjCoord)]; } else if (adjLetter !== '.' + letter) { plot.edges++; } } adjLetters.push(adjLetter ? adjLetter.replace('.', '') : '_'); }); for (let i = 1; i < 8; i += 2) { let cornerLetter = adjLetters[i]; let beforeLetter = adjLetters[i - 1]; let afterLetter = adjLetters[i + 1] || adjLetters[0]; if (cornerLetter === letter && (beforeLetter === letter || afterLetter === letter)) { continue; } if ( (beforeLetter === letter && afterLetter === letter) || (beforeLetter !== letter && afterLetter !== letter) ) { plot.corners++; } } return adj; } for (let y = 0; y < plots.length; y++) { const row = plots[y]; for (let x = 0; x < row.length; x++) { const char = row[x]; if (char.startsWith('.')) { continue; } regions.push(getAllAdjacentPlots({ x, y })); } } let sum = 0; regions.forEach((plots) => { const perim = plots.reduce((carry, { edges }) => carry + edges, 0); const vertices = plots.reduce((carry, { corners }) => carry + corners, 0); const area = plots.length; // Part 1 // sum += perim * area; // Part 2 sum += vertices * area; }); console.log(sum);