Solve 2024-16 (part 1)
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="2024-16" type="BunRunConfiguration">
|
||||||
|
<option name="program" value="2024/16/run.ts" />
|
||||||
|
<option name="workingDirectory" value="$PROJECT_DIR$" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import { describe, expect, it } from 'bun:test';
|
||||||
|
import { solveFirst, solveSecond } from './index.ts';
|
||||||
|
|
||||||
|
describe('2024-16', () => {
|
||||||
|
it('first', () => {
|
||||||
|
const testInput = `###############
|
||||||
|
#.......#....E#
|
||||||
|
#.#.###.#.###.#
|
||||||
|
#.....#.#...#.#
|
||||||
|
#.###.#####.#.#
|
||||||
|
#.#.#.......#.#
|
||||||
|
#.#.#####.###.#
|
||||||
|
#...........#.#
|
||||||
|
###.#.#####.#.#
|
||||||
|
#...#.....#.#.#
|
||||||
|
#.#.#.###.#.#.#
|
||||||
|
#.....#...#.#.#
|
||||||
|
#.###.#.#.#.#.#
|
||||||
|
#S..#.....#...#
|
||||||
|
###############`;
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
expect(solveFirst(testInput)).toBe(7036);
|
||||||
|
expect(
|
||||||
|
solveFirst(`#################
|
||||||
|
#...#...#...#..E#
|
||||||
|
#.#.#.#.#.#.#.#.#
|
||||||
|
#.#.#.#...#...#.#
|
||||||
|
#.#.#.#.###.#.#.#
|
||||||
|
#...#.#.#.....#.#
|
||||||
|
#.#.#.#.#.#####.#
|
||||||
|
#.#...#.#.#.....#
|
||||||
|
#.#.#####.#.###.#
|
||||||
|
#.#.#.......#...#
|
||||||
|
#.#.###.#####.###
|
||||||
|
#.#.#...#.....#.#
|
||||||
|
#.#.#.#####.###.#
|
||||||
|
#.#.#.........#.#
|
||||||
|
#.#.#.#########.#
|
||||||
|
#S#.............#
|
||||||
|
#################`)
|
||||||
|
).toBe(11048);
|
||||||
|
expect(
|
||||||
|
solveFirst(`####################################################
|
||||||
|
#......................................#..........E#
|
||||||
|
#......................................#...........#
|
||||||
|
#....................#.................#...........#
|
||||||
|
#....................#.................#...........#
|
||||||
|
#....................#.................#...........#
|
||||||
|
#....................#.................#...........#
|
||||||
|
#....................#.................#...........#
|
||||||
|
#....................#.................#...........#
|
||||||
|
#....................#.................#...........#
|
||||||
|
#....................#.................#...........#
|
||||||
|
#....................#.............................#
|
||||||
|
#S...................#.............................#
|
||||||
|
####################################################`)
|
||||||
|
).toBe(5078);
|
||||||
|
expect(
|
||||||
|
solveFirst(`###########################
|
||||||
|
#######################..E#
|
||||||
|
######################..#.#
|
||||||
|
#####################..##.#
|
||||||
|
####################..###.#
|
||||||
|
###################..##...#
|
||||||
|
##################..###.###
|
||||||
|
#################..####...#
|
||||||
|
################..#######.#
|
||||||
|
###############..##.......#
|
||||||
|
##############..###.#######
|
||||||
|
#############..####.......#
|
||||||
|
############..###########.#
|
||||||
|
###########..##...........#
|
||||||
|
##########..###.###########
|
||||||
|
#########..####...........#
|
||||||
|
########..###############.#
|
||||||
|
#######..##...............#
|
||||||
|
######..###.###############
|
||||||
|
#####..####...............#
|
||||||
|
####..###################.#
|
||||||
|
###..##...................#
|
||||||
|
##..###.###################
|
||||||
|
#..####...................#
|
||||||
|
#.#######################.#
|
||||||
|
#S........................#
|
||||||
|
###########################`)
|
||||||
|
).toBe(21148);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it('second', () => {
|
||||||
|
// TODO: add second input
|
||||||
|
const testInput = ``;
|
||||||
|
// TODO: add second solution
|
||||||
|
expect(solveSecond(testInput)).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { findCoordsOfDigit } from '../../utils/coordinates.ts';
|
||||||
|
import { PriorityQueue } from '../../utils/queue.ts';
|
||||||
|
|
||||||
|
export function solveFirst(input: string): number {
|
||||||
|
const map = input.split('\n');
|
||||||
|
const [x, y] = findCoordsOfDigit(map, 'S')[0];
|
||||||
|
const start = { x, y, score: 0, dx: 1, dy: 0 };
|
||||||
|
const possibleOptions = new PriorityQueue<typeof start>();
|
||||||
|
|
||||||
|
possibleOptions.enqueue(start, 0);
|
||||||
|
const visited = new Set<`${number}:${number}:${number}:${number}`>();
|
||||||
|
visited.add(`${start.x}:${start.y}:${start.dx}:${start.dy}`);
|
||||||
|
|
||||||
|
while (possibleOptions.size() > 0) {
|
||||||
|
const el = possibleOptions.dequeue()!!;
|
||||||
|
visited.add(`${el.node.x}:${el.node.y}:${el.node.dx}:${el.node.dy}`);
|
||||||
|
if (map[el.node.y][el.node.x] === 'E') {
|
||||||
|
return el.node.score;
|
||||||
|
}
|
||||||
|
for (let [nx, ny, score, ndx, ndy] of [
|
||||||
|
[
|
||||||
|
el.node.x + el.node.dx,
|
||||||
|
el.node.y + el.node.dy,
|
||||||
|
el.node.score + 1,
|
||||||
|
el.node.dx,
|
||||||
|
el.node.dy
|
||||||
|
],
|
||||||
|
[el.node.x, el.node.y, el.node.score + 1000, el.node.dy, -el.node.dx],
|
||||||
|
[el.node.x, el.node.y, el.node.score + 1000, -el.node.dy, el.node.dx]
|
||||||
|
]) {
|
||||||
|
if (map[ny][nx] === '#') continue;
|
||||||
|
if (visited.has(`${nx}:${ny}:${ndx}:${ndy}`)) continue;
|
||||||
|
possibleOptions.enqueue({ x: nx, y: ny, score, dx: ndx, dy: ndy }, score);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function solveSecond(input: string): number {
|
||||||
|
// TODO: add code
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { join } from 'path';
|
||||||
|
import { solveFirst, solveSecond } from './index.ts';
|
||||||
|
|
||||||
|
const input = await Bun.file(join(__dirname, 'input.txt')).text();
|
||||||
|
|
||||||
|
const firstAnswer = solveFirst(input);
|
||||||
|
|
||||||
|
console.log(firstAnswer);
|
||||||
|
|
||||||
|
const secondAnswer = solveSecond(input);
|
||||||
|
|
||||||
|
console.log(secondAnswer);
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
export class PriorityQueue<T> {
|
||||||
|
private readonly values: { node: T; priority: number }[] = [];
|
||||||
|
|
||||||
|
enqueue(node: T, priority: number) {
|
||||||
|
this.values.push({ node, priority });
|
||||||
|
this._bubbleUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
dequeue() {
|
||||||
|
if (this.values.length === 0) return null;
|
||||||
|
|
||||||
|
const min = this.values[0];
|
||||||
|
const end = this.values.pop();
|
||||||
|
|
||||||
|
if (this.values.length > 0) {
|
||||||
|
this.values[0] = end!;
|
||||||
|
this._sinkDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
size() {
|
||||||
|
return this.values.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
_bubbleUp() {
|
||||||
|
let idx = this.values.length - 1;
|
||||||
|
const element = this.values[idx];
|
||||||
|
|
||||||
|
while (idx > 0) {
|
||||||
|
const parentIdx = Math.floor((idx - 1) / 2);
|
||||||
|
const parent = this.values[parentIdx];
|
||||||
|
|
||||||
|
if (element.priority >= parent.priority) break;
|
||||||
|
|
||||||
|
this.values[parentIdx] = element;
|
||||||
|
this.values[idx] = parent;
|
||||||
|
idx = parentIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_sinkDown() {
|
||||||
|
let idx = 0;
|
||||||
|
const length = this.values.length;
|
||||||
|
const element = this.values[0];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const leftChildIdx = 2 * idx + 1;
|
||||||
|
const rightChildIdx = 2 * idx + 2;
|
||||||
|
let leftChild, rightChild;
|
||||||
|
let swap = null;
|
||||||
|
|
||||||
|
if (leftChildIdx < length) {
|
||||||
|
leftChild = this.values[leftChildIdx];
|
||||||
|
if (leftChild.priority < element.priority) {
|
||||||
|
swap = leftChildIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rightChildIdx < length) {
|
||||||
|
rightChild = this.values[rightChildIdx];
|
||||||
|
if (
|
||||||
|
(swap === null && rightChild.priority < element.priority) ||
|
||||||
|
(swap !== null && rightChild.priority < leftChild!.priority)
|
||||||
|
) {
|
||||||
|
swap = rightChildIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (swap === null) break;
|
||||||
|
|
||||||
|
this.values[idx] = this.values[swap];
|
||||||
|
this.values[swap] = element;
|
||||||
|
idx = swap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user