Skip to content

Commit 8cf0bc2

Browse files
committed
Added 2017 day 25
1 parent 07428e9 commit 8cf0bc2

File tree

4 files changed

+207
-2
lines changed

4 files changed

+207
-2
lines changed

2017/24/code.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default class {
4747
let visConsole = new Console();
4848
if (visualization)
4949
this.visContainer.append(visConsole.container);
50-
let x = 0;
50+
5151
let bridges = [new Bridge([[0, 0]], components)];
5252
let resultBridges = [];
5353
while (bridges.length > 0) {
@@ -61,7 +61,6 @@ let x = 0;
6161
newComponentsLeft.splice(i, 1);
6262
let newBridge = new Bridge([...bridge.bridgeComponents.slice(), component[0] == pins ? [component[0], component[1]] : [component[1], component[0]]], newComponentsLeft);
6363
newBridges.push(newBridge);
64-
x++;
6564

6665
if (resultBridges.length == 0)
6766
resultBridges.push(newBridge);

2017/25/code.mjs

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
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+
this.noPart2 = true;
14+
}
15+
16+
/**
17+
* Parses the puzzle input.
18+
* @param {string} input Puzzle input.
19+
* @returns {{
20+
* startState: string,
21+
* numberOfSteps: number,
22+
* stateRules: object<string,Rule>,
23+
* }} Replacements and medicine molecule.
24+
*/
25+
parse(input) {
26+
let consoleLine = this.solConsole.addLine("Parsing...");
27+
28+
let blocks = input.trim().split(/\r?\n\r?\n/);
29+
if (blocks.length < 2)
30+
throw new Error("Invalid input data");
31+
32+
let headerLines = blocks[0].split(/\r?\n/);
33+
if (headerLines.length != 2)
34+
throw new Error("Invalid header");
35+
let match = headerLines[0].match(/^Begin in state ([A-Z]).$/);
36+
if (match == null)
37+
throw new Error("Invalid initial state");
38+
let startState = match[1];
39+
match = headerLines[1].match(/^Perform a diagnostic checksum after (\d+) steps?.$/);
40+
if (match == null)
41+
throw new Error("Invalid number of steps state");
42+
let numberOfSteps = parseInt(match[1]);
43+
44+
let stateRules = {};
45+
46+
blocks.slice(1).forEach((block, blockIndex) => {
47+
let blockLines = block.split(/\r?\n/).map(e => e.trim());
48+
if (blockLines.length != 9)
49+
throw new Error(`Invalid data in rule ${blockIndex + 1}`);
50+
match = blockLines[0].match(/^In state ([A-Z]):$/)
51+
if (match == null)
52+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 1`);
53+
let ruleState = match[1];
54+
if (ruleState in stateRules)
55+
throw new Error(`Rule for state ${ruleState} is defined more than once`);
56+
57+
let valuesToWrite = [], moves = [], nextStates = [];
58+
if (blockLines[1] != "If the current value is 0:")
59+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 2`);
60+
match = blockLines[2].match(/^- Write the value (0|1).$/);
61+
if (match == null)
62+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 3`);
63+
valuesToWrite.push(parseInt(match[1]));
64+
match = blockLines[3].match(/^- Move one slot to the (left|right).$/);
65+
if (match == null)
66+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 4`);
67+
moves.push(parseInt(match[1] == "left" ? -1 : 1));
68+
match = blockLines[4].match(/^- Continue with state ([A-Z]).$/);
69+
if (match == null)
70+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 5`);
71+
nextStates.push(match[1]);
72+
73+
if (blockLines[5] != "If the current value is 1:")
74+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 6`);
75+
match = blockLines[6].match(/^- Write the value (0|1).$/);
76+
if (match == null)
77+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 7`);
78+
valuesToWrite.push(parseInt(match[1]));
79+
match = blockLines[7].match(/^- Move one slot to the (left|right).$/);
80+
if (match == null)
81+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 8`);
82+
moves.push(parseInt(match[1] == "left" ? -1 : 1));
83+
match = blockLines[8].match(/^- Continue with state ([A-Z]).$/);
84+
if (match == null)
85+
throw new Error(`Invalid data in rule ${blockIndex + 1} line 9`);
86+
nextStates.push(match[1]);
87+
88+
stateRules[ruleState] = new Rule(valuesToWrite, moves, nextStates);
89+
});
90+
91+
consoleLine.innerHTML += " done.";
92+
return {startState, numberOfSteps, stateRules};
93+
}
94+
95+
/**
96+
* Finds the diagnostic checksum.
97+
* @param {number} part Puzzle part.
98+
* @param {string} input Puzzle input.
99+
* @param {boolean} visualization Enable visualization.
100+
* @returns {number} Diagnostic checksum.
101+
*/
102+
async solve(part, input, visualization) {
103+
try {
104+
this.isSolving = true;
105+
106+
let {startState, numberOfSteps, stateRules} = this.parse(input);
107+
108+
let visConsole = new Console();
109+
if (visualization)
110+
this.visContainer.append(visConsole.container);
111+
112+
let onePositions = new Set(), position = 0, state = startState;
113+
for (let i = 0; i < numberOfSteps; i++) {
114+
let rule = stateRules[state];
115+
if (rule == undefined)
116+
throw new Error(`Invalid state ${state}`);
117+
if (!onePositions.has(position)) {
118+
if (rule.valuesToWrite[0] == 1)
119+
onePositions.add(position);
120+
position += rule.moves[0];
121+
state = rule.nextStates[0];
122+
}
123+
else {
124+
if (rule.valuesToWrite[1] == 0)
125+
onePositions.delete(position);
126+
position += rule.moves[1];
127+
state = rule.nextStates[1];
128+
}
129+
}
130+
131+
let numberOfOnes = onePositions.size;
132+
if (visualization)
133+
visConsole.addLine(`After ${numberOfSteps} step${numberOfSteps == 1 ? "" : "s"} "1" appears <span class="highlighted">${numberOfOnes}</span> time${numberOfOnes == 1 ? "" : "s"} on the tape.`);
134+
135+
return numberOfOnes;
136+
}
137+
138+
finally {
139+
this.isSolving = false;
140+
}
141+
}
142+
143+
/**
144+
* Stops solving the puzzle.
145+
*/
146+
async stopSolving() {
147+
this.isStopping = true;
148+
while (this.isSolving)
149+
await(delay(10));
150+
this.isStopping = false;
151+
}
152+
}
153+
154+
/**
155+
* Puzzle rule class.
156+
*/
157+
class Rule {
158+
/**
159+
* @param {number[]} valuesToWrite Values to write if current value is 0 or 1.
160+
* @param {number[]} moves Moves if current value is 0 or 1.
161+
* @param {string[]} nextStates Next states if current value is 0 or 1.
162+
*/
163+
constructor(valuesToWrite, moves, nextStates) {
164+
/**
165+
* Values to write if current value is 0 or 1.
166+
* @type {number[]}
167+
*/
168+
this.valuesToWrite = valuesToWrite;
169+
/**
170+
* Moves if current value is 0 or 1.
171+
* @type {number[]}
172+
*/
173+
this.moves = moves;
174+
/**
175+
* Next states if current value is 0 or 1.
176+
* @type {string[]}
177+
*/
178+
this.nextStates = nextStates;
179+
}
180+
}

2017/25/testInput.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Begin in state A.
2+
Perform a diagnostic checksum after 6 steps.
3+
4+
In state A:
5+
If the current value is 0:
6+
- Write the value 1.
7+
- Move one slot to the right.
8+
- Continue with state B.
9+
If the current value is 1:
10+
- Write the value 0.
11+
- Move one slot to the left.
12+
- Continue with state B.
13+
14+
In state B:
15+
If the current value is 0:
16+
- Write the value 1.
17+
- Move one slot to the left.
18+
- Continue with state A.
19+
If the current value is 1:
20+
- Write the value 1.
21+
- Move one slot to the right.
22+
- Continue with state A.

tree.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,10 @@ export const years = [
494494
{
495495
name: "Day 24: Electromagnetic Moat", path: "./2017/24", taskUrl: "https://adventofcode.com/2017/day/24",
496496
answers: {part1: 31, part2: 19}
497+
},
498+
{
499+
name: "Day 25: The Halting Problem", path: "./2017/25", taskUrl: "https://adventofcode.com/2017/day/25",
500+
answers: {part1: 3}
497501
}
498502
]
499503
},

0 commit comments

Comments
 (0)