Skip to content

Commit

Permalink
Merge pull request #40 from hildjj/day20
Browse files Browse the repository at this point in the history
Day 20
  • Loading branch information
hildjj authored Dec 20, 2024
2 parents ccdcb53 + 71dafe9 commit 414e54d
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 1 deletion.
2 changes: 2 additions & 0 deletions day20.peggy
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
lines = (@[#.SE]+ "\n")+

109 changes: 109 additions & 0 deletions day20.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { PointSet } from './lib/rect.ts';
import { AllDirs, Point, PointMap, Rect } from './lib/rect.ts';
import { type MainArgs, parseFile } from './lib/utils.ts';
import { BinaryHeap } from '@std/data-structures';

type Parsed = string[][];

function astar(r: Rect, start: Point, end: Point): PointSet {
const gScore = new PointMap([[start, 0]]);
const fScore = new PointMap([[start, 0]]);
const prev = new PointMap<Point>();
const backlog = new BinaryHeap<Point>(
(a, b) => fScore.get(a)! - fScore.get(b)!,
);
backlog.push(start);

while (!backlog.isEmpty()) {
const p = backlog.pop()!;
const g = gScore.get(p)!;

if (p.equals(end)) {
const ps = new PointSet();
let n: Point | undefined = end;
while (n) {
ps.add(n);
n = prev.get(n);
}
return ps;
}

for (const d of AllDirs) {
const next = p.inDir(d);
if (r.check(next) && (r.get(next) !== '#')) {
const nextG = gScore.get(next) ?? Infinity;
if (g + 1 < nextG) {
gScore.set(next, g + 1);
fScore.set(next, g + next.manhattan(end));
backlog.push(next);
prev.set(next, p);
}
}
}
}

return new PointSet();
}

function part1(inp: Parsed): number {
const r = new Rect(inp);
const [start] = r.filter((v) => v === 'S');
const [end] = r.filter((v) => v === 'E');

const ps = astar(r, start, end);
const pss = ps.size;
const target = pss - 100;
let tot = 0;
let pcount = 0;
for (const p of ps) {
let qcount = 0;
for (const q of ps) {
if (p.equals(q)) {
continue;
}
const d = p.manhattan(q);
if (d === 2) {
if ((pcount + (pss - qcount) + 1) <= target) {
tot++;
}
}
qcount++;
}
pcount++;
}
return tot;
}

function part2(inp: Parsed): number {
const r = new Rect(inp);
const [start] = r.filter((v) => v === 'S');
const [end] = r.filter((v) => v === 'E');

const ps = astar(r, start, end);
const pss = ps.size;
const target = pss - 100;
let tot = 0;
let pcount = 0;
for (const p of ps) {
let qcount = 0;
for (const q of ps) {
if (p.equals(q)) {
continue;
}
const d = p.manhattan(q);
if (d <= 20) {
if ((pcount + (pss - qcount) + d - 1) <= target) {
tot++;
}
}
qcount++;
}
pcount++;
}
return tot;
}

export default async function main(args: MainArgs): Promise<[number, number]> {
const inp = await parseFile<Parsed>(args);
return [part1(inp), part2(inp)];
}
2 changes: 1 addition & 1 deletion inputs
1 change: 1 addition & 0 deletions test/day20.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default [1429, 988931];

0 comments on commit 414e54d

Please sign in to comment.