-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaoc_day10_p2.ts
executable file
·131 lines (109 loc) · 4.2 KB
/
aoc_day10_p2.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env -S deno run --quiet --allow-read=./
/**
* @file aoc_day10_p2.ts
* @brief Advent of Code (AOC) 2021 Puzzle solution for: Day 10 Part 2.
*
* @author simon rowe <simon@wiremoons.com>
* @license open-source released under "MIT License"
*
* @date originally created: 17 Dec 2021
*
* @details Advent of Code (AOC) 2021 Puzzle solution. See: https://adventofcode.com/2021/
*
* @note The program can be run with Deno using the command:
* @code deno run --quiet --allow-read ./aoc_day10_p2.ts
*/
//--------------------------------
// MODULE IMPORTS
//--------------------------------
// import modules to support program:
import {existsFile, isString} from "https://deno.land/x/deno_mod@0.7.4/mod.ts";
//--------------------------------
// MAIN
//--------------------------------
if (import.meta.main) {
//********************************
// APPLICATION CONFIGURATION
//********************************
// define the base location for Deno application directories:
const aocDay = "10";
const aocPart = "02";
// SET INPUT PUZZLE DATA FILE NAME:
// Puzzle data:
const inputFile = `./day${aocDay}-input.txt`;
// Puzzle data 'TEST':
//const inputFile = `./day${aocDay}-TEST-input.txt`;
//********************************
// Display startup message
console.log(`\nAdvent Of Code 2021 : Day ${aocDay} Part ${aocPart}\n`);
// Ensure the 'puzzle input' file can be found and loaded
if (!await existsFile(inputFile)) {
console.error(`\nERROR: failed to find the puzzle input file: '${inputFile}'. Exit.\n`);
Deno.exit(1);
}
/**/
// Read in the puzzle data
const puzzleData = await Deno.readTextFile(inputFile);
// read puzzle data into lines of text
const lines = puzzleData.split("\n");
// convert lines into an array per line
const lineArray = Array.from(lines);
console.log(` » Checking total of '${lineArray.length}' chunks for any corruption...`);
// for each line of puzzle input get the incomplete chuck lines only as an array of opening chucks
const completionArray = lineArray.map((line) => getIncomplete(line)).filter(Boolean);
console.log(` » Found '${completionArray.length}' chunks requiring completion.`);
//console.debug(completionArray);
// calculate completion score for Part 2
const completionReversed = completionArray.map(incompleteChunk => incompleteChunk!.reverse()
.reduce((score, c) => score * 5 + getCompletionAmount(c), 0))
.sort((a, b) => a - b);
//console.debug(completionReversed);
const middleScore = completionReversed[Math.floor(completionReversed.length / 2)];
console.log(` » PART 2: chunk completion score is: '${middleScore}'`);
console.log("\nDONE");
}
//--------------------------------
// FUNCTIONS
//--------------------------------
/**
* Find any corrupt chuck in each line of puzzle data input.
* @param chunkLine string contain one line from the puzzle file.
* @returns the corrupted chunk found as one of ') ] } >' or undefined
*/
function getIncomplete(chunkLine: string): string[] | undefined {
const chunks: Record<string, string> = {
"(": ")",
"[": "]",
"{": "}",
"<": ">",
};
const stack: string[] = [];
// Re-use code from Part 1 to remove corrupted lines
for (const char of chunkLine.split("")) {
if (char in chunks) {
stack.push(char);
} else if (char !== chunks[stack.pop()!]) {
//console.debug("FOUND chuck syntax error\n");
return undefined;
}
}
// line processed is not corrupt - so return the 'stack' array for 'Part 2' processing
//console.debug("No chuck syntax error found!\n");
return stack;
}
/**
* Find the score value for a completed chuck.
* @param completionChar string contain one of '( [ { >'
* @returns the score value for the corrupted chunk or 0 if not found
*/
function getCompletionAmount(completionChar:string | undefined):number {
const scoring: Record<string, number> = {
"(": 1,
"[": 2,
"{": 3,
"<": 4
};
if (! (isString(completionChar))) return 0;
if (! (completionChar in scoring)) return 0;
return scoring[completionChar]!;
}