This repository has been archived by the owner on Mar 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
94 lines (78 loc) · 2.71 KB
/
index.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
import AdventCommand from '~shared/advent-command';
import { parseFile, splitLines } from '~shared/file';
type Input = string[];
export default class Day10Challenge extends AdventCommand<Input> {
private readonly opening = ['(', '[', '{', '<'];
private readonly closing = [')', ']', '}', '>'];
static aliases = ['day:10'];
protected async parseInput(test: boolean): Promise<Input> {
const data = await parseFile(test ? 'testinput' : 'input', __dirname);
return splitLines(data);
}
private checkLineSyntax(line: string, onError?: (char: string) => void): string[] {
const syntax = [...line];
const stack: string[] = [];
for (const char of syntax) {
if (this.opening.includes(char)) {
stack.push(char);
} else if (this.closing.includes(char)) {
if (stack[stack.length - 1] === this.opening[this.closing.indexOf(char)]) {
stack.pop();
} else {
if (onError) {
onError(char);
}
break;
}
} else {
throw new Error(`Invalid character '${char}'`);
}
}
return stack;
}
protected part1(input: Input): number {
let totalError = 0;
for (const line of input) {
this.checkLineSyntax(line, (char) => {
switch (char) {
case ')':
totalError += 3;
break;
case ']':
totalError += 57;
break;
case '}':
totalError += 1197;
break;
case '>':
totalError += 25_137;
break;
}
});
}
return totalError;
}
protected part2(input: Input): number {
const incompleteInputLines: string[] = [];
for (const line of input) {
let error = false;
this.checkLineSyntax(line, () => {
error = true;
});
if (!error) {
incompleteInputLines.push(line);
}
}
const scores: number[] = [];
for (const line of incompleteInputLines) {
const stack = this.checkLineSyntax(line);
let score = 0;
for (const char of stack.reverse()) {
score *= 5;
score += this.opening.indexOf(char) + 1;
}
scores.push(score);
}
return scores.sort((a, b) => a - b)[Math.floor(scores.length / 2)];
}
}