Skip to content

Commit

Permalink
before optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
shahata committed Dec 16, 2024
1 parent b359edb commit 2a7151a
Show file tree
Hide file tree
Showing 3 changed files with 318 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/2024/day16.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const opposite = { up: "down", down: "up", left: "right", right: "left" };

function solve(input, part2 = false) {
let map = input.split("\n").map(line => line.split(""));
let sy = map.findIndex(line => line.includes("S"));
let sx = map[sy].indexOf("S");
let ey = map.findIndex(line => line.includes("E"));
let ex = map[ey].indexOf("E");
let current = { x: sx, y: sy, score: 0, dir: "right", path: ["0,0"] };
let queue = [current];
let visited = new Map();
let min = Infinity;
let paths = [];
visited.set(`${current.x},${current.y}`, 0);
while (queue.length > 0) {
current = queue.shift();
if (current.x === ex && current.y === ey) {
if (current.score < min) paths = [current.path];
if (current.score === min) paths.push(current.path);
min = Math.min(min, current.score);
continue;
}
let neighbors = [
{ x: current.x - 1, y: current.y, dir: "left" },
{ x: current.x + 1, y: current.y, dir: "right" },
{ x: current.x, y: current.y - 1, dir: "up" },
{ x: current.x, y: current.y + 1, dir: "down" },
]
.filter(neighbor => neighbor.dir !== opposite[current.dir])
.filter(neighbor => map[neighbor.y]?.[neighbor.x] !== "#")
.map(neighbor => ({
...neighbor,
path: current.path.concat(`${neighbor.x},${neighbor.y}`),
score: current.score + (neighbor.dir !== current.dir ? 1001 : 1),
}));
neighbors.forEach(neighbor => {
if (
!visited.has(`${neighbor.x},${neighbor.y},${neighbor.dir}`) ||
visited.get(`${neighbor.x},${neighbor.y},${neighbor.dir}`) >
neighbor.score
) {
queue.push(neighbor);
visited.set(
`${neighbor.x},${neighbor.y},${neighbor.dir}`,
neighbor.score + (part2 ? 1 : 0),
);
}
});
}
return { min, paths };
}

export function part1(input) {
return solve(input).min;
}

export function part2(input) {
return solve(input, true).paths.reduce(
(acc, path) => acc.union(new Set(path)),
new Set(),
).size;
}
114 changes: 114 additions & 0 deletions src/2024/day16.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { part1, part2 } from "./day16.js";
import readInput from "../utils/read-input.js";

const input = readInput(import.meta.url);

describe("day16 2024", () => {
describe("part1", () => {
test("it should work for part 1 examples", () => {
expect(
part1(
[
"###############",
"#.......#....E#",
"#.#.###.#.###.#",
"#.....#.#...#.#",
"#.###.#####.#.#",
"#.#.#.......#.#",
"#.#.#####.###.#",
"#...........#.#",
"###.#.#####.#.#",
"#...#.....#.#.#",
"#.#.#.###.#.#.#",
"#.....#...#.#.#",
"#.###.#.#.#.#.#",
"#S..#.....#...#",
"###############",
].join("\n"),
),
).toEqual(7036);

expect(
part1(
[
"#################",
"#...#...#...#..E#",
"#.#.#.#.#.#.#.#.#",
"#.#.#.#...#...#.#",
"#.#.#.#.###.#.#.#",
"#...#.#.#.....#.#",
"#.#.#.#.#.#####.#",
"#.#...#.#.#.....#",
"#.#.#####.#.###.#",
"#.#.#.......#...#",
"#.#.###.#####.###",
"#.#.#...#.....#.#",
"#.#.#.#####.###.#",
"#.#.#.........#.#",
"#.#.#.#########.#",
"#S#.............#",
"#################",
].join("\n"),
),
).toEqual(11048);
});

test("it should work for part 1 input", () => {
expect(part1(input)).toEqual(106512);
});
});

describe("part2", () => {
test("it should work for part 2 examples", () => {
expect(
part2(
[
"###############",
"#.......#....E#",
"#.#.###.#.###.#",
"#.....#.#...#.#",
"#.###.#####.#.#",
"#.#.#.......#.#",
"#.#.#####.###.#",
"#...........#.#",
"###.#.#####.#.#",
"#...#.....#.#.#",
"#.#.#.###.#.#.#",
"#.....#...#.#.#",
"#.###.#.#.#.#.#",
"#S..#.....#...#",
"###############",
].join("\n"),
),
).toEqual(45);

expect(
part2(
[
"#################",
"#...#...#...#..E#",
"#.#.#.#.#.#.#.#.#",
"#.#.#.#...#...#.#",
"#.#.#.#.###.#.#.#",
"#...#.#.#.....#.#",
"#.#.#.#.#.#####.#",
"#.#...#.#.#.....#",
"#.#.#####.#.###.#",
"#.#.#.......#...#",
"#.#.###.#####.###",
"#.#.#...#.....#.#",
"#.#.#.#####.###.#",
"#.#.#.........#.#",
"#.#.#.#########.#",
"#S#.............#",
"#################",
].join("\n"),
),
).toEqual(64);
});

test("it should work for part 2 input", () => {
expect(part2(input)).toEqual(563);
});
});
});
Loading

0 comments on commit 2a7151a

Please sign in to comment.