-
Notifications
You must be signed in to change notification settings - Fork 0
/
day10.ts
57 lines (51 loc) · 1.32 KB
/
day10.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import { Point, PointSet, Rect } from './lib/rect.ts';
import { type MainArgs, parseFile } from './lib/utils.ts';
type Parsed = number[][];
function hike(r: Rect<number>, p: Point, next: number, peaks: PointSet): void {
for (const n of p.cardinal(r)) {
if (r.get(n) === next) {
if (next === 9) {
peaks.add(n);
} else {
hike(r, n, next + 1, peaks);
}
}
}
}
function hike2(r: Rect<number>, p: Point, next: number): number {
// I expected to have to memoize or work from the back to get a solution
// that worked fast enough.
let count = 0;
for (const n of p.cardinal(r)) {
if (r.get(n) === next) {
if (next === 9) {
count++;
} else {
count += hike2(r, n, next + 1);
}
}
}
return count;
}
function part1(inp: Parsed): number {
const r = new Rect(inp);
let tot = 0;
for (const p of r.filter((v) => v === 0)) {
const peaks = new PointSet();
hike(r, p, 1, peaks);
tot += peaks.size;
}
return tot;
}
function part2(inp: Parsed): number {
const r = new Rect(inp);
let tot = 0;
for (const p of r.filter((v) => v === 0)) {
tot += hike2(r, p, 1);
}
return tot;
}
export default async function main(args: MainArgs): Promise<[number, number]> {
const inp = await parseFile<Parsed>(args);
return [part1(inp), part2(inp)];
}