Skip to content

Commit

Permalink
optimized day 16
Browse files Browse the repository at this point in the history
  • Loading branch information
shahata committed Dec 16, 2024
1 parent 6f52fec commit 4db8ae2
Showing 1 changed file with 21 additions and 22 deletions.
43 changes: 21 additions & 22 deletions src/2024/day16.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
const opposite = { up: "down", down: "up", left: "right", right: "left" };

function parse(input) {
let map = input.split("\n").map(line => line.split(""));
let sy = map.findIndex(line => line.includes("S"));
let sx = map[sy].indexOf("S");
let y = map.findIndex(line => line.includes("S"));
let x = map[y].indexOf("S");
let ey = map.findIndex(line => line.includes("E"));
let ex = map[ey].indexOf("E");
return { map, start: { x: sx, y: sy }, end: { x: ex, y: ey } };
return { map, start: { x, y, direction: "right" }, end: { x: ex, y: ey } };
}

function getNeighbors(current, map) {
const opposite = { up: "down", down: "up", left: "right", right: "left" };
let neighbors = [
{ x: current.x - 1, y: current.y, direction: "left" },
{ x: current.x + 1, y: current.y, direction: "right" },
Expand All @@ -20,34 +19,34 @@ function getNeighbors(current, map) {
.filter(n => map[n.y]?.[n.x] !== "#")
.map(n => ({
...n,
path: current.path.concat(`${n.x},${n.y}`),
path: current.path.union(new Set([`${n.x},${n.y}`])),
score: current.score + (n.direction !== current.direction ? 1001 : 1),
}));
return neighbors;
}

function solve(input, part2 = false) {
function solve(input) {
let { map, start, end } = parse(input);
let current = { ...start, score: 0, direction: "right", path: ["0,0"] };
let queue = [current];
let curr = { ...start, score: 0, path: new Set([`${start.x},${start.y}`]) };
let queue = [curr];
let visited = new Map();
let results = [{ score: Infinity }];
visited.set(`${current.x},${current.y}`, 0);
const key = p => `${p.x},${p.y},${p.direction}`;
visited.set(key(curr), curr);
while (queue.length > 0) {
current = queue.shift();
if (current.x === end.x && current.y === end.y) {
if (current.score < results[0].score) results = [current];
if (current.score === results[0].score) results.push(current);
curr = queue.shift();
if (curr.x === end.x && curr.y === end.y) {
if (curr.score < results[0].score) results = [curr];
if (curr.score === results[0].score) results.push(curr);
continue;
}
getNeighbors(current, map).forEach(n => {
const prev = visited.get(`${n.x},${n.y},${n.direction}`) || Infinity;
// for part two we follow also paths with same score passing the same cell
// this can easily be optimized by saving the path and going in only once
// alternatively we could use dfs with memoization to optimize the search
if (prev > n.score || (part2 && prev === n.score)) {
getNeighbors(curr, map).forEach(n => {
const prev = visited.get(key(n));
if (!prev || prev.score > n.score) {
queue.push(n);
visited.set(`${n.x},${n.y},${n.direction}`, n.score);
visited.set(key(n), n);
} else if (prev.score === n.score) {
prev.path = prev.path.union(n.path);
}
});
}
Expand All @@ -59,6 +58,6 @@ export function part1(input) {
}

export function part2(input) {
const results = solve(input, true).map(result => new Set(result.path));
const results = solve(input).map(result => result.path);
return results.reduce((acc, next) => acc.union(next)).size;
}

0 comments on commit 4db8ae2

Please sign in to comment.