Skip to content

Commit 4f7238b

Browse files
committed
Added 2017 day 08
1 parent 02204af commit 4f7238b

4 files changed

Lines changed: 181 additions & 1 deletion

File tree

2017/07/code.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ export default class {
4444
return programs;
4545
}
4646

47-
4847
/**
4948
* Finds the name of the bottom program (part 1) or the correct weight of the program with the wrong weight (part 2).
5049
* @param {number} part Puzzle part.

2017/08/code.mjs

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
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 {Instruction[]} Instruction.
19+
*/
20+
parse(input) {
21+
let consoleLine = this.solConsole.addLine("Parsing...");
22+
23+
let instructions = input.trim().split(/\r?\n/).map((line, index) => {
24+
let match = line.match(/^([a-z]+) (dec|inc) (-?\d+) if ([a-z]+) (>|<|>=|<=|==|!=) (-?\d+)$/);
25+
if (match == null)
26+
throw new Error(`Invalid data in line ${index + 1}`);
27+
return new Instruction(match[1], match[2], parseInt(match[3]), match[4], match[5], parseInt(match[6]))
28+
});
29+
30+
consoleLine.innerHTML += " done.";
31+
return instructions;
32+
}
33+
34+
/**
35+
* Finds the largest register value after completing the instructions (part 1) or the highest value held in any register during this process (part 2).
36+
* @param {number} part Puzzle part.
37+
* @param {string} input Puzzle input.
38+
* @param {boolean} visualization Enable visualization.
39+
* @returns {number} Largest register value after completing the instructions (part 1) or the highest value held in any register during this process (part 2).
40+
*/
41+
async solve(part, input, visualization) {
42+
try {
43+
this.isSolving = true;
44+
45+
let instructions = this.parse(input);
46+
47+
let visConsole = new Console();
48+
let solConsoleLine1, solConsoleLine2;
49+
if (visualization) {
50+
this.visContainer.append(visConsole.container);
51+
this.solConsole.addLine(`Number of instructions: ${instructions.length}.`);
52+
solConsoleLine1 = this.solConsole.addLine();
53+
if (part == 2)
54+
solConsoleLine2 = this.solConsole.addLine();
55+
}
56+
57+
let registers = {};
58+
for (let instruction of instructions) {
59+
if (!(instruction.arithmeticRegister in registers))
60+
registers[instruction.arithmeticRegister] = 0;
61+
if (!(instruction.conditionRegister in registers))
62+
registers[instruction.conditionRegister] = 0;
63+
}
64+
65+
let registerNames = Object.keys(registers);
66+
if (visualization)
67+
registerNames.forEach(e => visConsole.addLine());
68+
69+
let maxRegisterValue = 0;
70+
for (let instructionIndex = 0; instructionIndex < instructions.length; instructionIndex++) {
71+
if (this.isStopping)
72+
return;
73+
74+
let instruction = instructions[instructionIndex];
75+
if ((instruction.conditionOperator == ">" && registers[instruction.conditionRegister] > instruction.conditionValue) ||
76+
(instruction.conditionOperator == "<" && registers[instruction.conditionRegister] < instruction.conditionValue) ||
77+
(instruction.conditionOperator == ">=" && registers[instruction.conditionRegister] >= instruction.conditionValue) ||
78+
(instruction.conditionOperator == "<=" && registers[instruction.conditionRegister] <= instruction.conditionValue) ||
79+
(instruction.conditionOperator == "==" && registers[instruction.conditionRegister] == instruction.conditionValue) ||
80+
(instruction.conditionOperator == "!=" && registers[instruction.conditionRegister] != instruction.conditionValue)) {
81+
82+
if (instruction.arithmeticOperator == "inc")
83+
registers[instruction.arithmeticRegister] += instruction.arithmeticValue;
84+
if (instruction.arithmeticOperator == "dec")
85+
registers[instruction.arithmeticRegister] -= instruction.arithmeticValue;
86+
87+
if (part == 2)
88+
maxRegisterValue = Math.max(maxRegisterValue, registers[instruction.arithmeticRegister]);
89+
}
90+
91+
if (visualization) {
92+
solConsoleLine1.innerHTML = `Instruction: ${instructionIndex + 1}.`;
93+
if (part == 2)
94+
solConsoleLine2.innerHTML = `Max register value: ${maxRegisterValue}.`;
95+
for (let i = 0; i < registerNames.length; i++)
96+
visConsole.lines[i].innerHTML = `${registerNames[i]} = ${registers[registerNames[i]]}`;
97+
await delay(1);
98+
}
99+
}
100+
101+
if (part == 1) {
102+
maxRegisterValue = Math.max(...Object.values(registers));
103+
if (visualization) {
104+
let maxValueRegisterIndex = registerNames.findIndex(e => registers[e] == maxRegisterValue);
105+
visConsole.lines[maxValueRegisterIndex].classList.add("highlighted");
106+
visConsole.container.scrollTop = visConsole.lines[maxValueRegisterIndex].offsetTop - visConsole.container.offsetHeight / 2;
107+
}
108+
}
109+
110+
return maxRegisterValue;
111+
}
112+
113+
finally {
114+
this.isSolving = false;
115+
}
116+
}
117+
118+
/**
119+
* Stops solving the puzzle.
120+
*/
121+
async stopSolving() {
122+
this.isStopping = true;
123+
while (this.isSolving)
124+
await(delay(10));
125+
this.isStopping = false;
126+
}
127+
}
128+
129+
/**
130+
* Puzzle instruction class.
131+
*/
132+
class Instruction {
133+
/**
134+
* @param {string} arithmeticRegister Arithmetic register.
135+
* @param {string} arithmeticOperator Arithmetic operator.
136+
* @param {number} arithmeticValue Arithmetic value.
137+
* @param {string} conditionRegister Condition register.
138+
* @param {string} conditionOperator Condition operator.
139+
* @param {number} conditionValue Condition value.
140+
*/
141+
constructor(arithmeticRegister, arithmeticOperator, arithmeticValue, conditionRegister, conditionOperator, conditionValue) {
142+
/**
143+
* Arithmetic register.
144+
* @type {string}
145+
*/
146+
this.arithmeticRegister = arithmeticRegister;
147+
/**
148+
* Arithmetic operator.
149+
* @type {string}
150+
*/
151+
this.arithmeticOperator = arithmeticOperator;
152+
/**
153+
* Arithmetic value.
154+
* @type {number}
155+
*/
156+
this.arithmeticValue = arithmeticValue;
157+
/**
158+
* Condition register.
159+
* @type {string}
160+
*/
161+
this.conditionRegister = conditionRegister;
162+
/**
163+
* Condition operator.
164+
* @type {string}
165+
*/
166+
this.conditionOperator = conditionOperator;
167+
/**
168+
* Condition value.
169+
* @type {number}
170+
*/
171+
this.conditionValue = conditionValue;
172+
}
173+
}

2017/08/testInput.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
b inc 5 if a > 1
2+
a inc 1 if b < 5
3+
c dec -10 if a >= 1
4+
c inc -20 if c == 10

tree.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ export const years = [
426426
{
427427
name: "Day 7: Recursive Circus", path: "./2017/07", taskUrl: "https://adventofcode.com/2017/day/7",
428428
answers: {part1: "tknk", part2: 60}
429+
},
430+
{
431+
name: "Day 8: I Heard You Like Registers", path: "./2017/08", taskUrl: "https://adventofcode.com/2017/day/8",
432+
answers: {part1: 1, part2: 10}
429433
}
430434
]
431435
},

0 commit comments

Comments
 (0)