@@ -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