-
Notifications
You must be signed in to change notification settings - Fork 1
/
day_10.ts
57 lines (49 loc) · 2.12 KB
/
day_10.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 assert from "assert/strict";
import { loadInput } from "./helpers";
const CHARACTER_PAIRS = { "(": ")", "[": "]", "{": "}", "<": ">" };
const OPENERS = Object.keys(CHARACTER_PAIRS);
const POINTS_BY_CORRUPT_CHARACTER = { ")": 3, "]": 57, "}": 1197, ">": 25137 };
const POINTS_PER_MISSING_CLOSER = { ")": 1, "]": 2, "}": 3, ">": 4 };
function pointValue(line: string): number {
let stack = [];
for (let index = 0; index < line.length; index++) {
const character = line.charAt(index);
if (OPENERS.includes(character)) {
stack.push(character);
} else { // This must be a closer
const expectedCloser = CHARACTER_PAIRS[stack.pop()];
if (character !== expectedCloser) { return POINTS_BY_CORRUPT_CHARACTER[character]; }
}
}
return 0;
}
function isCorrupt(line: string): boolean { return pointValue(line) !== 0; }
function missingCharacters(line: string): string {
let stack = [];
for (let index = 0; index < line.length; index++) {
const character = line.charAt(index);
if (OPENERS.includes(character)) {
stack.push(character);
} else { // This must be a closer
const expectedCloser = CHARACTER_PAIRS[stack.pop()];
assert.strictEqual(character, expectedCloser, "Unexpected mismatch in incomplete line");
}
}
// At this point, our stack contains all remaining unclosed openers.
return stack.reverse().map(c => CHARACTER_PAIRS[c]).join('');
}
function calcIncompleteScore(missingChars: string): number {
let score = 0;
for (let index = 0; index < missingChars.length; index++) {
score *= 5;
score += POINTS_PER_MISSING_CLOSER[missingChars.charAt(index)];
}
return score;
}
const lines = loadInput("day_10.input").split("\n");
console.log("Part 1", lines.map(pointValue).reduce((a, b) => a + b));
const incompleteLines = lines.filter(l => !isCorrupt(l));
const scores = incompleteLines.map(missingCharacters).map(calcIncompleteScore);
scores.sort((a, b) => a - b);
const middleScoreIndex = (scores.length - 1) / 2;
console.log("Part 2", scores[middleScoreIndex]);