import fs from 'node:fs' const data = fs.readFileSync('input.txt', { encoding: "utf-8" }, data => data) const filter_struct = /[^0-9.\n]/gms const filter_data = /\d+/gms const structureMap = [] const filtered_elements = [...data.matchAll(filter_struct)] const lines = data.split('\n') let res = 0 // --- filling array with unknown characters for (let y = 0; y < lines.length; y++) { const found_struct = [...lines[y].matchAll(filter_struct)] found_struct.forEach(struct => { structureMap.push({ name: struct[0], x: struct.index, y: y }) }) } // --- part 1 --------------------------------------------------------- for (let y = 0; y < lines.length; y++) { const found_numbers = [...lines[y].matchAll(filter_data)] found_numbers.forEach(number => { let result = false result = isStructAroundMe(lines, { line: lines[y], y: y, x: number.index, xEnd: number.index + number[0].length - 1 }) res += result ? parseInt(number[0]) : 0 }) } console.log(res) // --- part 2 --------- console.log(`part2`.padEnd(30, '-')) let result2 = 0 structureMap.filter(struct => struct.name === '*').forEach(structure => { const neighbours = findNeighbours(structure) result2 += neighbours.length === 2 ? neighbours.reduce((cur, next) => cur * next) : 0 }) console.log(result2) function findNeighbours(structure) { const directions = getDirections(structure.x, structure.y) let chars = [] directions.forEach(direction => { let char = lines[direction.y][direction.x] if (!isNaN(char)) { let re = new RegExp("(([0-9]+)?" + char + "([0-9]+)?)", "gm") chars.push(parseInt([...lines[direction.y].matchAll(re)].find(number => direction.x <= (number.index + number[0].length - 1))[0])) } }) chars = [...new Set(chars)] return chars } function getNumberFromLine(line) { "".match() } function getDirections(x, y) { const directions = [...new Set([ { x: Math.max(0, x - 1), y: Math.max(0, y - 1) }, { x: x, y: Math.max(0, y - 1) }, { x: Math.min(lines[0].length - 1, x + 1), y: Math.max(0, y - 1) }, { x: Math.max(0, x - 1), y: y }, { x: Math.min(lines[0].length - 1, x + 1), y: y }, { x: Math.max(0, x - 1), y: Math.min(lines.length - 1, y + 1) }, { x: x, y: Math.min(lines.length - 1, y + 1) }, { x: Math.min(lines[0].length - 1, x + 1), y: Math.min(lines.length - 1, y + 1) } ])] return directions } // ----- function findStructure(lines, x, y) { if (!lines) return false let result = structureMap.find(coords => coords.x === x && coords.y === y) ? true : false return result } function isStructAroundMe(lines, pos) { let result = false const directions = [...new Set([ { x: Math.max(pos.x - 1, 0), y: Math.max(pos.y - 1, 0) }, { x: Math.max(pos.x - 1, 0), y: pos.y }, { x: Math.max(pos.x - 1, 0), y: Math.min(pos.y + 1, lines.length - 1) }, { x: Math.min(pos.xEnd + 1, (pos.line).length), y: Math.max(pos.y - 1, 0) }, { x: Math.min(pos.xEnd + 1, (pos.line).length), y: pos.y }, { x: Math.min(pos.xEnd + 1, (pos.line).length), y: Math.min(pos.y + 1, lines.length - 1) } ])] for (let x = pos.x; x <= pos.xEnd; x++) { directions.push({ x: x, y: Math.max(pos.y - 1, 0) }) directions.push({ x: x, y: Math.min(pos.y + 1, lines.length - 1) }) } directions.forEach(direction => { if (result === true) { return true } if (findStructure(lines, direction.x, direction.y)) { result = true } }) return result }