Skip to content

Commit 010a4ed

Browse files
committed
Added 2017 day 14
1 parent 4558bed commit 010a4ed

File tree

4 files changed

+140
-3
lines changed

4 files changed

+140
-3
lines changed

2017/13/code.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default class {
2222
/**
2323
* Parses the puzzle input.
2424
* @param {string} input Puzzle input.
25-
* @returns {number[]} Scanner ranges.
25+
* @returns {string[]} Scanner ranges.
2626
*/
2727
parse(input) {
2828
let consoleLine = this.solConsole.addLine("Parsing...");
@@ -45,11 +45,11 @@ export default class {
4545

4646

4747
/**
48-
* Finds the severity of trip through the firewall.
48+
* Finds the severity of trip through the firewall (part 1) or the minimum delay of the packet to pass through the firewall without being caught (part 2).
4949
* @param {number} part Puzzle part.
5050
* @param {string} input Puzzle input.
5151
* @param {boolean} visualization Enable visualization.
52-
* @returns {number} Severity of trip through the firewall.
52+
* @returns {number} Severity of trip through the firewall (part 1) or the minimum delay of the packet to pass through the firewall without being caught (part 2).
5353
*/
5454
async solve(part, input, visualization) {
5555
try {

2017/14/code.mjs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import { delay, Console, Vector2D, PixelMap } from "../../utility.mjs";
2+
3+
const usedSquareColorIndex = 1;
4+
const usedSquareColor = "#999999";
5+
const regionColors = ["#999999", "#ffffff", "#00aa00", "#ffff00"];
6+
7+
export default class {
8+
/**
9+
* @param {Console} solConsole Solution console.
10+
* @param {HTMLElement} visContainer Visualization container.
11+
*/
12+
constructor(solConsole, visContainer) {
13+
this.isSolving = false;
14+
this.isStopping = false;
15+
this.solConsole = typeof solConsole !== "undefined" ? solConsole : new Console();
16+
this.visContainer = visContainer;
17+
}
18+
19+
/**
20+
* Parses the puzzle input.
21+
* @param {string} input Puzzle input.
22+
* @returns {string} Key string.
23+
*/
24+
parse(input) {
25+
let consoleLine = this.solConsole.addLine("Parsing...");
26+
27+
let keyString = input.trim();
28+
29+
consoleLine.innerHTML += " done.";
30+
return keyString;
31+
}
32+
33+
34+
/**
35+
* Finds the number of used grid squares (part 1) or the number of regions (part 2).
36+
* @param {number} part Puzzle part.
37+
* @param {string} input Puzzle input.
38+
* @param {boolean} visualization Enable visualization.
39+
* @returns {number} Number of used grid squares (part 1) or the number of regions (part 2).
40+
*/
41+
async solve(part, input, visualization) {
42+
try {
43+
this.isSolving = true;
44+
45+
let keyString = this.parse(input);
46+
47+
let pixelMap = new PixelMap(128, 128);
48+
if (visualization) {
49+
this.visContainer.append(pixelMap.container);
50+
pixelMap.palette[usedSquareColorIndex] = usedSquareColor;
51+
regionColors.forEach((e, i) => pixelMap.palette[usedSquareColorIndex + 1 + i] = e);
52+
}
53+
54+
let numberOfUsedSquares = 0;
55+
56+
// Calculate hashes and draw the map
57+
for (let y = 0; y < pixelMap.height; y++) {
58+
let lengths = [...`${keyString}-${y}`.split("").map(e => e.charCodeAt(0)), 17, 31, 73, 47, 23];
59+
let list = new Array(256).fill(null).map((e, i) => i);
60+
let currentPosition = 0, skipSize = 0;
61+
for (let round = 0; round < 64; round++) {
62+
for (let length of lengths) {
63+
let newList = list.slice();
64+
for (let i = 0; i < length; i++)
65+
newList[(currentPosition + i) % list.length] = list[(currentPosition + length - 1 - i) % list.length];
66+
list = newList;
67+
currentPosition = (currentPosition + length + (skipSize++)) % list.length;
68+
}
69+
}
70+
let denseHash = [];
71+
for (let i = 0; i < 16; i++)
72+
denseHash.push(...list.slice(i * 16, (i + 1) * 16).reduce((acc, e) => acc ^ e, 0).toString(2).padStart(8, "0").split("").map(e => e != "0" ? 1 : 0));
73+
74+
numberOfUsedSquares += denseHash.reduce((acc, e) => acc += e, 0);
75+
76+
denseHash.forEach((e, x) => pixelMap.drawPixel(x, y, e != 0 ? usedSquareColorIndex : 0));
77+
}
78+
79+
// Fill the regions in the map
80+
if (part == 1)
81+
return numberOfUsedSquares;
82+
83+
let regionIndex = 2;
84+
for (let x = 0; x < pixelMap.width; x++) {
85+
for (let y = 0; y < pixelMap.height; y++) {
86+
if (pixelMap.image[y][x] == 1) {
87+
let squares = [new Vector2D(x, y)];
88+
while (squares.length) {
89+
let newSquares = [];
90+
for (let square of squares) {
91+
[new Vector2D(1, 0), new Vector2D(0, 1), new Vector2D(-1, 0), new Vector2D(0, -1)]
92+
.map(e => e.add(square))
93+
.filter(e => e.x >= 0 && e.x < pixelMap.width && e.y >= 0 && e.y < pixelMap.height && pixelMap.image[e.y][e.x] == 1)
94+
.forEach(e => {
95+
newSquares.push(e);
96+
pixelMap.image[e.y][e.x] = regionIndex
97+
});
98+
}
99+
squares = newSquares;
100+
}
101+
regionIndex++;
102+
}
103+
}
104+
}
105+
106+
if (visualization) {
107+
for (let x = 0; x < pixelMap.width; x++) {
108+
for (let y = 0; y < pixelMap.height; y++) {
109+
if (pixelMap.image[y][x] != 0)
110+
pixelMap.drawPixel(x, y, usedSquareColorIndex + 1 + (pixelMap.image[y][x] % regionColors.length));
111+
}
112+
}
113+
}
114+
115+
return regionIndex - 2;
116+
}
117+
118+
finally {
119+
this.isSolving = false;
120+
}
121+
}
122+
123+
/**
124+
* Stops solving the puzzle.
125+
*/
126+
async stopSolving() {
127+
this.isStopping = true;
128+
while (this.isSolving)
129+
await(delay(10));
130+
this.isStopping = false;
131+
}
132+
}

2017/14/testInput.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
flqrgnkx

tree.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,10 @@ export const years = [
450450
{
451451
name: "Day 13: Packet Scanners", path: "./2017/13", taskUrl: "https://adventofcode.com/2017/day/13",
452452
answers: {part1: 24, part2: 10}
453+
},
454+
{
455+
name: "Day 14: Disk Defragmentation", path: "./2017/14", taskUrl: "https://adventofcode.com/2017/day/14",
456+
answers: {part1: 8108, part2: 1242}
453457
}
454458
]
455459
},

0 commit comments

Comments
 (0)