Files
advent-of-code/2023/day03/index.js
2024-12-17 12:22:01 +01:00

99 lines
3.6 KiB
JavaScript

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
}