Skip to content

Commit fc0e1a2

Browse files
committed
Added 2017 day 12
1 parent a13d2a6 commit fc0e1a2

4 files changed

Lines changed: 140 additions & 6 deletions

File tree

2017/11/code.mjs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { delay, Console, Vector2D } from "../../utility.mjs";
22

3-
const wallIndex = 1;
4-
const wallColor = "#999999";
5-
const positionColorIndex = 2;
6-
const positionColor = "#ffffff";
7-
83
export default class {
94
/**
105
* @param {Console} solConsole Solution console.
@@ -25,7 +20,7 @@ export default class {
2520
parse(input) {
2621
let consoleLine = this.solConsole.addLine("Parsing...");
2722

28-
let path = input.trim().split(",").map((step, index) => {
23+
let path = input.trim().split(",").map((step, index) => {
2924
if (["n", "s", "ne", "nw", "se", "sw"].indexOf(step) < 0)
3025
throw new Error(`Invalid data in step ${index + 1}`);
3126
return step;

2017/12/code.mjs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import { delay, Console } from "../../utility.mjs";
2+
3+
export default class {
4+
/**
5+
* @param {Console} solConsole Solution console.
6+
* @param {HTMLElement} visContainer Visualization container.
7+
*/
8+
constructor(solConsole, visContainer) {
9+
this.isSolving = false;
10+
this.isStopping = false;
11+
this.solConsole = typeof solConsole !== "undefined" ? solConsole : new Console();
12+
this.visContainer = visContainer;
13+
}
14+
15+
/**
16+
* Parses the puzzle input.
17+
* @param {string} input Puzzle input.
18+
* @returns {Program[]} Programs.
19+
*/
20+
parse(input) {
21+
let consoleLine = this.solConsole.addLine("Parsing...");
22+
23+
let programs = [];
24+
input.trim().split(/\r?\n/).forEach((line, index) => {
25+
let match = line.match(/^(\d+) <-> (\d+(, \d+)*)$/);
26+
if (match == null)
27+
throw new Error(`Invalid data in line ${index + 1}`);
28+
let program = programs.find(e => e.id == parseInt(match[1]));
29+
if (program == undefined)
30+
programs.push(program = new Program(parseInt(match[1])));
31+
32+
for (let connectedProgramId of match[2].split(", ").map(e => parseInt(e))) {
33+
let connectedProgram = programs.find(e => e.id == connectedProgramId);
34+
if (connectedProgram == undefined)
35+
programs.push(connectedProgram = new Program(connectedProgramId));
36+
program.connections.push(connectedProgram);
37+
connectedProgram.connections.push(program);
38+
}
39+
});
40+
41+
consoleLine.innerHTML += " done.";
42+
return programs;
43+
}
44+
45+
/**
46+
* Finds the number of programs in the group that contains program ID 0 (part 1) or the number of program groups (part 2).
47+
* @param {number} part Puzzle part.
48+
* @param {string} input Puzzle input.
49+
* @param {boolean} visualization Enable visualization.
50+
* @returns {number} Number of programs in the group that contains program ID 0 (part 1) or the number of program groups (part 2).
51+
*/
52+
async solve(part, input, visualization) {
53+
try {
54+
this.isSolving = true;
55+
56+
let programs = this.parse(input).sort((a, b) => a - b);
57+
if (programs[0].id != 0)
58+
throw new Error("Program 0 not found");
59+
60+
let visConsole = new Console();
61+
if (visualization)
62+
this.visContainer.append(visConsole.container);
63+
64+
let addGroupIdsToSet = (program, idSet) => {
65+
if (!idSet.has(program.id)) {
66+
idSet.add(program.id);
67+
program.connections.forEach(e => addGroupIdsToSet(e, idSet));
68+
}
69+
}
70+
71+
let groups = [];
72+
while (programs.length > 0) {
73+
let idSet = new Set();
74+
addGroupIdsToSet(programs[0], idSet);
75+
groups.push(programs.filter(e => idSet.has(e.id)).sort((a, b) => a - b));
76+
programs = programs.filter(e => !idSet.has(e.id));
77+
}
78+
79+
if (visualization) {
80+
if (part == 1)
81+
visConsole.addLine(`Group (<span class="highlighted">${groups[0].length}</span> program${groups.length == 1 ? "" : "s"}): ${groups[0].map(e => e.id).join(", ")}.`);
82+
else {
83+
for (let i = 0; i < groups.length; i++) {
84+
visConsole.addLine(`Group ${i + 1}: ${groups[i].map(e => e.id).join(", ")}.`);
85+
visConsole.addLine();
86+
}
87+
}
88+
}
89+
90+
return part == 1 ? groups[0].length : groups.length;
91+
}
92+
93+
finally {
94+
this.isSolving = false;
95+
}
96+
}
97+
98+
/**
99+
* Stops solving the puzzle.
100+
*/
101+
async stopSolving() {
102+
this.isStopping = true;
103+
while (this.isSolving)
104+
await(delay(10));
105+
this.isStopping = false;
106+
}
107+
}
108+
109+
/**
110+
* Puzzle program class.
111+
*/
112+
class Program {
113+
/**
114+
* @param {number} id ID.
115+
*/
116+
constructor(id) {
117+
/**
118+
* ID.
119+
* @type {number}
120+
*/
121+
this.id = id;
122+
/**
123+
* Connections.
124+
* @type {Program[]}
125+
*/
126+
this.connections = [];
127+
}
128+
}

2017/12/testInput.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
0 <-> 2
2+
1 <-> 1
3+
2 <-> 0, 3, 4
4+
3 <-> 2, 4
5+
4 <-> 2, 3, 6
6+
5 <-> 6
7+
6 <-> 4, 5

tree.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ export const years = [
442442
{
443443
name: "Day 11: Hex Ed", path: "./2017/11", taskUrl: "https://adventofcode.com/2017/day/11",
444444
answers: {part1: 3, part2: 3}
445+
},
446+
{
447+
name: "Day 12: Digital Plumber", path: "./2017/12", taskUrl: "https://adventofcode.com/2017/day/12",
448+
answers: {part1: 6, part2: 2}
445449
}
446450
]
447451
},

0 commit comments

Comments
 (0)