@@ -260,63 +260,32 @@ fn inner_part2(s: &[u8]) -> u32 {
260260 let y = y as u8 ;
261261
262262 for line_i in & quads[ Dir :: N as usize ] [ qy * QUADS_SIZE + qx] {
263+ let x = x as i16 ;
264+ let y = y as i16 ;
263265 let Some ( line) = lines[ Dir :: N as usize ] . get ( * line_i) else {
264266 continue ;
265267 } ;
266- let dist = x. abs_diff ( line. line_offset ) ;
268+ let dist = x. abs_diff ( line. line_offset as i16 ) as i16 ;
267269 if dist > 20 {
268270 continue ;
269271 }
272+ let dist_from_start = line. line_start as i16 - y;
270273
271- let mut line_ns = line. start_ns ;
272- for line_y in ( line. line_end ..line. line_start + 1 ) . rev ( ) {
273- let dist = dist + y. abs_diff ( line_y) ;
274- if dist > 20 {
275- line_ns += 1 ;
276- continue ;
277- }
278- let diff = ns - line_ns;
279- if diff >= MIN_CHEAT + dist as u16 {
280- sum += 1 ;
281- }
282- line_ns += 1 ;
274+ let ns_at_intersection = line. start_ns as i16 + dist_from_start;
275+ let diff_at_intersection = ns as i16 - ns_at_intersection;
276+ if diff_at_intersection - dist < MIN_CHEAT as i16 {
277+ continue ;
283278 }
279+ let cheat_left = ( diff_at_intersection - dist) - MIN_CHEAT as i16 ;
284280
285- // let line_len = line.line_start - line.line_end;
286-
287- // let offset_x = line.line_offset.abs_diff(x);
288- // if offset_x > 20 {
289- // continue;
290- // }
291-
292- // if line.line_start <= y {
293- // let offset_y = y - line.line_start;
294- // let offset = offset_x + offset_y;
295- // if offset > 20 {
296- // continue;
297- // }
298-
299- // let diff = ns - line.start_ns;
300- // if diff >= MIN_CHEAT + offset as u16 {
301- // let diff_left = diff - (MIN_CHEAT + offset as u16);
302- // sum += (offset as u32 - 20)
303- // .min(line_len as u32)
304- // .min((diff_left / 2 + 1) as u32);
305- // }
306- // } else if line.line_end >= y {
307- // let offset_y = line.line_end - y;
308- // let offset = offset_x + offset_y;
309- // if offset > 20 {
310- // continue;
311- // }
281+ let cheat_start = ( y + ( 20 - dist) ) . min ( line. line_start as i16 ) ;
282+ let cheat_end = ( y - ( 20 - dist) )
283+ . max ( y - cheat_left / 2 )
284+ . max ( line. line_end as i16 ) ;
312285
313- // let diff = ns - (line.start_ns + line_len as u16);
314-
315- // if diff >= MIN_CHEAT + offset as u16 {
316- // sum += (offset as u32 - 20).min(line_len as u32);
317- // }
318- // } else {
319- // }
286+ if cheat_start >= cheat_end {
287+ sum += ( cheat_start - cheat_end) as u32 + 1 ;
288+ }
320289 }
321290 for line_i in & quads[ Dir :: E as usize ] [ qy * QUADS_SIZE + qx] {
322291 let Some ( line) = lines[ Dir :: E as usize ] . get ( * line_i) else {
@@ -342,27 +311,54 @@ fn inner_part2(s: &[u8]) -> u32 {
342311 }
343312 }
344313 for line_i in & quads[ Dir :: S as usize ] [ qy * QUADS_SIZE + qx] {
314+ let x = x as i16 ;
315+ let y = y as i16 ;
345316 let Some ( line) = lines[ Dir :: S as usize ] . get ( * line_i) else {
346317 continue ;
347318 } ;
348- let dist = x. abs_diff ( line. line_offset ) ;
319+ let dist = x. abs_diff ( line. line_offset as i16 ) as i16 ;
349320 if dist > 20 {
350321 continue ;
351322 }
323+ let dist_from_start = y - line. line_start as i16 ;
352324
353- let mut line_ns = line. start_ns ;
354- for line_y in line. line_start ..line. line_end + 1 {
355- let dist = dist + y. abs_diff ( line_y) ;
356- if dist > 20 {
357- line_ns += 1 ;
358- continue ;
359- }
360- let diff = ns - line_ns;
361- if diff >= MIN_CHEAT + dist as u16 {
362- sum += 1 ;
363- }
364- line_ns += 1 ;
325+ let ns_at_intersection = line. start_ns as i16 + dist_from_start;
326+ let diff_at_intersection = ns as i16 - ns_at_intersection;
327+ if diff_at_intersection - dist < MIN_CHEAT as i16 {
328+ continue ;
365329 }
330+ let cheat_left = ( diff_at_intersection - dist) - MIN_CHEAT as i16 ;
331+
332+ let cheat_start = ( y - ( 20 - dist) ) . max ( line. line_start as i16 ) ;
333+ let cheat_end = ( y + ( 20 - dist) )
334+ . min ( y + cheat_left / 2 )
335+ . min ( line. line_end as i16 ) ;
336+
337+ if cheat_end >= cheat_start {
338+ sum += ( cheat_end - cheat_start) as u32 + 1 ;
339+ }
340+
341+ // let Some(line) = lines[Dir::S as usize].get(*line_i) else {
342+ // continue;
343+ // };
344+ // let dist = (x as u8).abs_diff(line.line_offset);
345+ // if dist > 20 {
346+ // continue;
347+ // }
348+
349+ // let mut line_ns = line.start_ns;
350+ // for line_y in line.line_start..line.line_end + 1 {
351+ // let dist = dist + (y as u8).abs_diff(line_y);
352+ // if dist > 20 {
353+ // line_ns += 1;
354+ // continue;
355+ // }
356+ // let diff = ns - line_ns;
357+ // if diff >= MIN_CHEAT + dist as u16 {
358+ // sum += 1;
359+ // }
360+ // line_ns += 1;
361+ // }
366362 }
367363 for line_i in & quads[ Dir :: W as usize ] [ qy * QUADS_SIZE + qx] {
368364 let Some ( line) = lines[ Dir :: W as usize ] . get ( * line_i) else {
0 commit comments