Skip to content

Commit 318c695

Browse files
committed
Working part two
1 parent a62439b commit 318c695

File tree

4 files changed

+193
-3
lines changed

4 files changed

+193
-3
lines changed

2016/9/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Answers
22

3-
| Part 1 | Part 2 |
4-
|----------|----------|
5-
| `120765` | ` ` |
3+
| Part 1 | Part 2 |
4+
|----------|---------------|
5+
| `120765` | `11658395076` |
66

77
## --- Day 9: Explosives in Cyberspace ---
88

2016/9/decompress-alg-2.js

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/**
2+
* Had to cheat for this one, looked up the algorithm on the
3+
* reddit solution thread. Seeing the algorithm, it makes total
4+
* sense but honestly not sure how long it would have taken me
5+
* to come up with that one.
6+
*
7+
* I've copied the post in its entirety below.
8+
*
9+
* @see https://www.reddit.com/r/adventofcode/comments/5hbygy/2016_day_9_solutions/dazentu/
10+
*/
11+
12+
/*
13+
In short the idea is to give each character in the input a weight, or
14+
multiplier if you will. Then for each character, as the input is read,
15+
increase its weight according to the decompression markers. This is roughly
16+
the steps taken:
17+
18+
- Initialise all characters weights to 1
19+
- Scan input one character at a time and
20+
- if it's a normal character, count its weight towards the total length
21+
- if it's the beginning of a marker, read the marker and multiply character
22+
weights forward in the input, according to the values of the marker.
23+
- Print out the value of length
24+
25+
-----------------------------------------------------------------------------
26+
27+
Using the second example from the puzzle description
28+
as an input; "X(8x2)(3x3)ABCY", the algorithm would run as follows:
29+
30+
1.
31+
32+
Weights: [111111111111111], length: 0
33+
34+
"X(8x2)(3x3)ABCY"
35+
^
36+
37+
X is a normal character, so we add its weight to length.
38+
39+
2.
40+
41+
Weights: [111111111111111], length: 1
42+
43+
"X(8x2)(3x3)ABCY"
44+
^
45+
46+
( is the beginning of a marker, so we read it and update the following
47+
weights according to its values.
48+
49+
3.
50+
51+
Weights: [111111222222221], length: 1
52+
53+
"X(8x2)(3x3)ABCY"
54+
^
55+
56+
( is the beginning of a marker, so we read it and update the following
57+
weights according to its values.
58+
59+
4.
60+
61+
Weights: [111111222226661], length: 1
62+
63+
"X(8x2)(3x3)ABCY"
64+
^
65+
66+
A is a normal character, so we add its weight to length.
67+
68+
5.
69+
70+
Weights: [111111222226661], length: 7
71+
72+
"X(8x2)(3x3)ABCY"
73+
^
74+
75+
B is a normal character, so we add its weight to length.
76+
77+
6.
78+
79+
Weights: [111111222226661], length: 13
80+
81+
"X(8x2)(3x3)ABCY"
82+
^
83+
84+
C is a normal character, so we add its weight to length.
85+
86+
7.
87+
88+
Weights: [111111222226661], length: 19
89+
90+
"X(8x2)(3x3)ABCY"
91+
^
92+
93+
Y is a normal character, so we add its weight to length.
94+
95+
8.
96+
97+
Weights: [111111222226661], length: 20
98+
99+
"X(8x2)(3x3)ABCY"
100+
^
101+
102+
We're at the end of input, so we read out the final result to be 20.
103+
*/
104+
105+
const decompress = str => {
106+
let weights = Array(str.length).fill(1);
107+
let total_length = 0;
108+
109+
let in_marker = false;
110+
111+
// Use objects so I can set my `filling` variable by reference.
112+
let chars = { val: '' },
113+
repeat = { val: '' };
114+
115+
let filling;
116+
117+
for (let i = 0; i < str.length; i++) {
118+
let char = str[i];
119+
120+
if (char === '(') {
121+
in_marker = true;
122+
123+
// Reset temp parsing variables
124+
chars.val = '';
125+
repeat.val = '';
126+
127+
// Reference `chars` that I am currently parsing
128+
filling = chars;
129+
} else if (in_marker) {
130+
if (char === 'x') {
131+
// Finished parsing `chars`, start parsing `repeat` next
132+
filling = repeat;
133+
} else if (char === ')') {
134+
// No longer in the marker
135+
in_marker = false;
136+
137+
// Parse our numbers
138+
let chars_int = parseInt(chars.val);
139+
let repeat_int = parseInt(repeat.val);
140+
141+
// Update the weights accordingly
142+
for (let c = 1; c <= chars_int; c++) {
143+
weights[i + c] *= repeat_int;
144+
}
145+
} else {
146+
// Extract the relevant characer into either `chars.val` or `repeat.val`
147+
filling.val += char;
148+
}
149+
} else {
150+
// Regular letter, add its weight to our total
151+
total_length += weights[i];
152+
}
153+
}
154+
155+
return total_length;
156+
};
157+
158+
module.exports = decompress;

2016/9/input.js

+18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

2016/9/part-two.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const assert = require('assert');
2+
const { input, sampleInputsPartTwo } = require('./input');
3+
const decompress = require('./decompress-alg-2');
4+
5+
// Tests
6+
sampleInputsPartTwo.forEach(({ str, decompressedLength }) => {
7+
let decompressed_test_str_length = decompress(str);
8+
9+
assert.strictEqual(decompressed_test_str_length, decompressedLength);
10+
});
11+
12+
let decompressed_str_length = decompress(input);
13+
14+
console.log(decompressed_str_length);

0 commit comments

Comments
 (0)