@@ -5,13 +5,10 @@ use utils::prelude::*;
55/// Finding shortcuts phasing through walls in a maze.
66#[ derive( Clone , Debug ) ]
77pub struct Day20 {
8- distances : Vec < Distance > ,
8+ distances : Vec < u16 > ,
99 cols : usize ,
1010}
1111
12- // Depending on AVX support, u16 or u32 can be faster
13- type Distance = u16 ;
14-
1512impl Day20 {
1613 pub fn new ( input : & str , _: InputType ) -> Result < Self , InputError > {
1714 let ( _, cols, mut grid) = grid:: from_str_padded ( input, 20 , b'#' , |b| match b {
@@ -37,24 +34,24 @@ impl Day20 {
3734 }
3835 grid[ end] = b'.' ;
3936
40- let mut distances = vec ! [ Distance :: MAX ; grid. len( ) ] ;
37+ let mut distances = vec ! [ u16 :: MAX ; grid. len( ) ] ;
4138 distances[ start] = 0 ;
4239 let mut queue = VecDeque :: new ( ) ;
43- queue. push_back ( ( start, 0 as Distance ) ) ;
44- while let Some ( ( index, distance ) ) = queue. pop_front ( ) {
40+ queue. push_back ( start) ;
41+ while let Some ( index) = queue. pop_front ( ) {
4542 if index == end {
4643 break ;
4744 }
4845
49- let Some ( next_distance) = distance . checked_add ( 1 ) else {
46+ let Some ( next_distance) = distances [ index ] . checked_add ( 1 ) else {
5047 return Err ( InputError :: new ( input, 0 , "path too long" ) ) ;
5148 } ;
5249
5350 for offset in [ 1 , cols as isize , -1 , -( cols as isize ) ] {
5451 let next = index. wrapping_add_signed ( offset) ;
55- if grid[ next] == b'.' && distances[ next] == Distance :: MAX {
52+ if grid[ next] == b'.' && distances[ next] == u16 :: MAX {
5653 distances[ next] = next_distance;
57- queue. push_back ( ( next, next_distance ) ) ;
54+ queue. push_back ( next) ;
5855 }
5956 }
6057 }
@@ -83,7 +80,7 @@ impl Day20 {
8380 }
8481
8582 fn cheat_count ( & self , x_offset : isize , y_offset : isize ) -> u32 {
86- let cheat_length = ( x_offset. unsigned_abs ( ) + y_offset. unsigned_abs ( ) ) as Distance ;
83+ let cheat_length = ( x_offset. unsigned_abs ( ) + y_offset. unsigned_abs ( ) ) as u16 ;
8784 if cheat_length == 0 {
8885 return 0 ;
8986 }
@@ -95,17 +92,15 @@ impl Day20 {
9592 {
9693 let this_distance = self . distances [ index] ;
9794 let target_distance = self . distances [ target] ;
98- cheats += u32:: from (
99- ( target_distance != Distance :: MAX )
100- & ( this_distance != Distance :: MAX )
101- & ( target_distance > this_distance. wrapping_add ( cheat_length) )
95+ cheats += u16:: from (
96+ ( target_distance != u16:: MAX )
10297 & ( target_distance
103- . wrapping_sub ( this_distance)
104- . wrapping_sub ( cheat_length)
98+ . saturating_sub ( this_distance)
99+ . saturating_sub ( cheat_length)
105100 >= 100 ) ,
106101 ) ;
107102 }
108- cheats
103+ cheats as u32
109104 }
110105}
111106
0 commit comments