Skip to content

Commit aeb4fd2

Browse files
committed
Adds optimized part two
1 parent 26ff4b4 commit aeb4fd2

File tree

2 files changed

+96
-35
lines changed

2 files changed

+96
-35
lines changed

2019/19/part-two.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ const { input } = require('./input');
22
const { TractorBeam } = require('./tractor-beam');
33

44
let tractor_beam = new TractorBeam(input);
5-
console.log(tractor_beam.partTwo());
5+
// console.log(tractor_beam.partTwo());
6+
console.log(tractor_beam.partTwoOptimized());

2019/19/tractor-beam.js

Lines changed: 94 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -127,51 +127,111 @@ class TractorBeam {
127127
return found_square.x * 10000 + found_square.y;
128128
}
129129

130+
// May not work in all cases (e.g. for slow slopes on top edge)
131+
partTwoOptimized(square_size = 100) {
132+
/**
133+
* First, we need to find when the tractor beam begins after the origin.
134+
* We do this by diagonalizing from 1,0 (or 0,1) until we hit 1 (being pulled).
135+
* Rather than just following a simple `y = x` line from the origin, we diagonalize
136+
* because the "slope" may be thin enough to not add pulled markers near the origin
137+
* (as I see with my puzzle input).
138+
*/
139+
this.grid.set(0, 0, 1);
140+
let start;
141+
let col = 1;
142+
let x = 1;
143+
let y = 0;
144+
while (!start) {
145+
let output = this.computeAt(x, y);
146+
147+
if (output === 1) {
148+
this.grid.set(x, y, 1);
149+
start = { x, y };
150+
break;
151+
}
152+
153+
if (x === 0) {
154+
x = ++col;
155+
y = 0;
156+
} else {
157+
x--;
158+
y++;
159+
}
160+
}
161+
162+
/**
163+
* Walk the top line and check bottom left from each point.
164+
*/
165+
let top_edge = { ...start };
166+
let found_top_left;
167+
while (!found_top_left) {
168+
let bottom_left_x = top_edge.x - square_size + 1;
169+
let bottom_left_y = top_edge.y + square_size - 1;
170+
let output = this.computeAt(bottom_left_x, bottom_left_y);
171+
this.grid.set(x, y, output);
172+
if (output) {
173+
found_top_left = { x: bottom_left_x, y: top_edge.y };
174+
} else {
175+
this.calculateNewEdges(undefined, top_edge, false);
176+
}
177+
}
178+
179+
// What value do you get if you take that
180+
// point's X coordinate, multiply it by 10000, then add the point's Y coordinate?
181+
console.log(found_top_left);
182+
return found_top_left.x * 10000 + found_top_left.y;
183+
}
184+
130185
/**
131186
* Updates edges in place.
132187
*/
133-
calculateNewEdges(bottom_edge, top_edge) {
134-
// First, move down until we hit 0
188+
calculateNewEdges(bottom_edge, top_edge, allow_for_bottom_jumps = true) {
135189
let output;
136-
do {
137-
bottom_edge.y++;
138-
let computer = new Computer({
139-
memory: this.memory,
140-
inputs: [bottom_edge.x, bottom_edge.y],
141-
});
142-
[output] = computer.run();
143-
this.grid.set(bottom_edge.x, bottom_edge.y, output);
144-
} while (output === 1);
145-
146-
// Then, move inward until we hit a `1`
147-
do {
148-
bottom_edge.x++;
149-
let computer = new Computer({
150-
memory: this.memory,
151-
inputs: [bottom_edge.x, bottom_edge.y],
152-
});
153-
[output] = computer.run();
154-
this.grid.set(bottom_edge.x, bottom_edge.y, output);
155-
} while (output === 0);
156-
157-
// Now do top edge
158-
do {
159-
// Double loops in case bottom calc mo
160-
top_edge.y++;
190+
191+
if (bottom_edge) {
192+
// First, move down until we hit 0
161193
do {
162-
// Move right until we hit a `0`
163-
top_edge.x++;
194+
bottom_edge.y++;
164195
let computer = new Computer({
165196
memory: this.memory,
166-
inputs: [top_edge.x, top_edge.y],
197+
inputs: [bottom_edge.x, bottom_edge.y],
167198
});
168199
[output] = computer.run();
169-
this.grid.set(top_edge.x, top_edge.y, output);
200+
this.grid.set(bottom_edge.x, bottom_edge.y, output);
170201
} while (output === 1);
171-
} while (top_edge.y !== bottom_edge.y);
172202

173-
// The cell immediately to the left of that is the right edge.
174-
top_edge.x--;
203+
// Then, move inward until we hit a `1`
204+
do {
205+
bottom_edge.x++;
206+
let computer = new Computer({
207+
memory: this.memory,
208+
inputs: [bottom_edge.x, bottom_edge.y],
209+
});
210+
[output] = computer.run();
211+
this.grid.set(bottom_edge.x, bottom_edge.y, output);
212+
} while (output === 0);
213+
}
214+
215+
if (top_edge) {
216+
// Now do top edge
217+
do {
218+
// Double loops in case bottom calc mo
219+
top_edge.y++;
220+
do {
221+
// Move right until we hit a `0`
222+
top_edge.x++;
223+
let computer = new Computer({
224+
memory: this.memory,
225+
inputs: [top_edge.x, top_edge.y],
226+
});
227+
[output] = computer.run();
228+
this.grid.set(top_edge.x, top_edge.y, output);
229+
} while (output === 1);
230+
} while (allow_for_bottom_jumps && top_edge.y !== bottom_edge.y);
231+
232+
// The cell immediately to the left of that is the right edge.
233+
top_edge.x--;
234+
}
175235
}
176236

177237
getWidth(bottom_edge, top_edge) {

0 commit comments

Comments
 (0)