-
Notifications
You must be signed in to change notification settings - Fork 0
/
day6.ts
78 lines (72 loc) · 1.74 KB
/
day6.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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import { Dir, Point, Rect } from './lib/rect.ts';
import { type MainArgs, parseFile } from './lib/utils.ts';
type Parsed = string[][];
function path(r: Rect): [Set<number>, Point] {
const [start] = r.filter((val) => val === '^');
let pos = start;
let dir = Dir.N;
const visited = new Set<number>();
while (true) {
visited.add(pos.toNumber());
const ahead = pos.inDir(dir);
if (!r.check(ahead)) {
break;
}
const char = r.get(ahead);
if (char === '.' || char === '^') {
pos = ahead;
} else {
dir = (dir + 1) % 4;
}
}
return [visited, start];
}
function path2(r: Rect): boolean {
const [start] = r.filter((val) => val === '^');
let pos = start;
let dir = Dir.N;
const visitedWithDir = new Set<string>();
while (true) {
const pwd = `${pos},${dir}`;
if (visitedWithDir.has(pwd)) {
return true;
}
visitedWithDir.add(pwd);
const ahead = pos.inDir(dir);
if (!r.check(ahead)) {
return false;
}
const char = r.get(ahead);
if (char === '.' || char === '^') {
pos = ahead;
} else {
dir = (dir + 1) % 4;
}
}
}
function part1(inp: Parsed): number {
const r = new Rect(inp);
const [visited] = path(r);
return visited.size;
}
function part2(inp: Parsed): number {
const r = new Rect(inp);
const [visited, start] = path(r);
const points = [...visited].map((v) => Point.fromNumber(v));
let tot = 0;
for (const p of points) {
if (p.equals(start)) {
continue;
}
r.set(p, '#');
if (path2(r)) {
tot++;
}
r.set(p, '.');
}
return tot;
}
export default async function main(args: MainArgs): Promise<[number, number]> {
const inp = await parseFile<Parsed>(args);
return [part1(inp), part2(inp)];
}