-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday12.ts
98 lines (81 loc) · 2.21 KB
/
day12.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import type { Day } from './Day.ts';
import { directNeighbors, enumGrid, isInGrid, type Pos } from './utils.ts';
export class DayImpl implements Day {
private readonly input: string[][];
constructor(input: string) {
this.input = this.parseInput(input);
}
parseInput(input: string) {
return input
.trim()
.split('\n')
.map((line: string) => {
return line
.split('');
});
}
partOne() {
let price = 0;
const visited = new Set<string>();
for (const { x, y } of enumGrid(this.input)) {
const key = `${y},${x}`;
if (!visited.has(key)) {
const { plotArea, edges } = getRegion([y, x], false, this.input, visited);
price += plotArea * edges;
}
}
return price;
}
partTwo() {
let price = 0;
const visited = new Set<string>();
for (const { x, y } of enumGrid(this.input)) {
const key = `${y},${x}`;
if (!visited.has(key)) {
const { plotArea, edges } = getRegion([y, x], true, this.input, visited);
price += plotArea * edges;
}
}
return price;
}
}
function getRegion(pos: Pos, bySide: boolean, grid: string[][], visited: Set<string>) {
let plotArea = 0;
const edges = new Set();
let edgeCount = 0;
const val = grid[pos[0]][pos[1]];
const queue = [pos];
while (queue.length > 0) {
const current = queue.shift()!;
const key = current.join(',');
if (visited.has(key)) {
continue;
}
visited.add(key);
plotArea += 1;
const neighbors = getNeighbors(current);
for (let polarity = 0; polarity < neighbors.length; polarity++) {
const [y, x] = neighbors[polarity];
if (!isInGrid(grid, y, x) || grid[y][x] !== val) {
edgeCount += 1;
edges.add(`${polarity},${y},${x}`);
if (bySide) {
for (const n2 of getNeighbors([y, x])) {
if (edges.has(`${polarity},${n2[0]},${n2[1]}`)) {
edgeCount -= 1;
}
}
}
}
else {
queue.push([y, x]);
}
}
}
return { plotArea, edges: edgeCount, val };
}
function getNeighbors(pos: Pos) {
return directNeighbors.map(([y, x]) => {
return [pos[0] + y, pos[1] + x] as Pos;
});
}