adventofcode/2023/16/impl.js

64 lines
1.8 KiB
JavaScript

const directions = {
"U": [-1, 0],
"D": [1, 0],
"L": [0, -1],
"R": [0, 1]
}
const mirrors = {
"/": {
"U": "R",
"D": "L",
"R": "U",
"L": "D"
},
"\\": {
"U": "L",
"D": "R",
"R": "D",
"L": "U"
}
}
const solve = (input) => {
const tiles = input.split('\n').map(line => line.split(''))
const energized = []
const outOfBounds = (pos) => pos[0] < 0 || pos[1] < 0 || pos[0] >= tiles.length || pos[1] >= tiles[0].length
const alreadyVisitedWithSameDirection = (pos, direction) => energized.find(e => e[0] === pos[0] && e[1] === pos[1] && e[2] === direction)
const traverse = (pos, direction) => {
if(outOfBounds(pos) || alreadyVisitedWithSameDirection(pos, direction))
return
const curr = tiles[pos[0]][pos[1]]
energized.push([pos[0], pos[1], direction])
if(curr === '/' || curr === '\\') {
direction = mirrors[curr][direction]
} else if(curr === '|' && (direction === "L" || direction === "R")) {
traverse([pos[0] + directions["U"][0], pos[1] + directions["U"][1]], "U")
traverse([pos[0] + directions["D"][0], pos[1] + directions["D"][1]], "D")
return
} else if(curr === '-' && (direction === "U" || direction === "D")) {
traverse([pos[0] + directions["L"][0], pos[1] + directions["L"][1]], "L")
traverse([pos[0] + directions["R"][0], pos[1] + directions["R"][1]], "R")
return
}
traverse([pos[0] + directions[direction][0], pos[1] + directions[direction][1]], direction)
}
traverse([0, 0], "R")
const print = () => {
toprint = []
tiles.forEach(t => toprint.push('.'.repeat(t.length).split('')))
energized.forEach(e => toprint[e[0]][e[1]] = '#')
console.log(toprint.map(tp => tp.join('')).join('\n'))
}
print()
// JS can't do obj/arr-in-arr Set comparisons, so I cheat by converting [1, 2] to "1,2"
return new Set(energized.map(e => [e[0], e[1]].toString())).size
}
module.exports = {
solve
}