@@ -47,24 +47,6 @@ impl Dir {
4747 Dir :: W => i. wrapping_sub ( 2 ) ,
4848 }
4949 }
50-
51- fn select_crosline ( & self , i : usize ) -> u8 {
52- ( match self {
53- Dir :: N => i / SIZE1 ,
54- Dir :: E => i % SIZE1 ,
55- Dir :: S => i / SIZE1 ,
56- Dir :: W => i % SIZE1 ,
57- } ) as u8
58- }
59-
60- fn select_inline ( & self , i : usize ) -> u8 {
61- ( match self {
62- Dir :: N => i % SIZE1 ,
63- Dir :: E => i / SIZE1 ,
64- Dir :: S => i % SIZE1 ,
65- Dir :: W => i / SIZE1 ,
66- } ) as u8
67- }
6850}
6951
7052#[ aoc( day20, part1) ]
@@ -139,110 +121,82 @@ pub fn part2(s: &str) -> u64 {
139121 }
140122}
141123
142- #[ derive( Debug ) ]
143- struct Line {
144- start_ns : u16 ,
145- line_start : u8 ,
146- lien_offset : u8 ,
147- }
148-
149- const QUAD_SIZE : usize = 8 ;
150- const QUADS_SIZE : usize = SIZE . div_ceil ( QUAD_SIZE ) ;
151- const QUADS_NEEDED : usize = 20usize . div_ceil ( QUAD_SIZE ) ;
152-
153124// #[target_feature(enable = "avx2,bmi1,bmi2,cmpxchg16b,lzcnt,movbe,popcnt")]
154125fn inner_part2 ( s : & [ u8 ] ) -> u64 {
155126 let start = memchr:: memchr ( b'S' , s) . unwrap ( ) ;
156127
157- let mut lines = [ const { heapless:: Vec :: < Line , 1024 > :: new ( ) } ; 4 ] ;
158- let mut quads =
159- [ const { [ const { heapless:: Vec :: < usize , 8 > :: new ( ) } ; QUADS_SIZE * QUADS_SIZE ] } ; 4 ] ;
128+ let mut ns_map = [ 0u16 ; SIZE1 * SIZE ] ;
160129
161130 let mut ns = 1 ;
162131
163- let mut i = start;
164- let mut d = if s[ i - 1 ] == b'.' {
132+ let mut d = if s[ start - 1 ] == b'.' {
165133 Dir :: W
166- } else if s[ i + 1 ] == b'.' {
134+ } else if s[ start + 1 ] == b'.' {
167135 Dir :: E
168- } else if s[ i - SIZE1 ] == b'.' {
136+ } else if s[ start - SIZE1 ] == b'.' {
169137 Dir :: N
170138 } else {
171139 Dir :: S
172140 } ;
173141
174- lines[ d as usize ]
175- . push ( Line {
176- start_ns : 0 ,
177- line_start : d. select_crosline ( i) ,
178- lien_offset : d. select_inline ( i) ,
179- } )
180- . unwrap ( ) ;
181-
182- let mut sum = 0 ;
142+ let mut cy = start as i32 / SIZE1 as i32 ;
143+ let mut cx = start as i32 % SIZE1 as i32 ;
183144
184- let mut prev_qx = usize:: MAX ;
185- let mut prev_qy = usize:: MAX ;
186- while s[ i] != b'E' {
187- let qx = ( i % SIZE1 ) / QUAD_SIZE ;
188- let qy = ( i / SIZE1 ) / QUAD_SIZE ;
189-
190- for qx in
191- qx. saturating_sub ( QUADS_NEEDED ) ..qx. saturating_add ( QUADS_NEEDED + 1 ) . min ( QUADS_SIZE )
192- {
193- for qy in
194- qy. saturating_sub ( QUADS_NEEDED ) ..qy. saturating_add ( QUADS_NEEDED + 1 ) . min ( QUADS_SIZE )
195- {
196- for line_i in & quads[ 0 ] [ qy * QUADS_SIZE + qx] {
197- sum += 1 ;
198- }
199- for line_i in & quads[ 1 ] [ qy * QUADS_SIZE + qx] {
200- sum += 1 ;
201- }
202- for line_i in & quads[ 2 ] [ qy * QUADS_SIZE + qx] {
203- sum += 1 ;
204- }
205- for line_i in & quads[ 3 ] [ qy * QUADS_SIZE + qx] {
206- sum += 1 ;
207- }
208- }
209- }
145+ let idx = |x, y| ( y * SIZE1 as i32 + x) as usize ;
210146
211- if prev_qy != qy || prev_qx != qx {
212- quads[ d as usize ] [ qy * QUADS_SIZE + qx]
213- . push ( lines[ d as usize ] . len ( ) - 1 )
214- . unwrap ( ) ;
215- }
216- prev_qy = qy;
217- prev_qx = qx;
147+ let mut sum = 0 ;
148+ while s[ idx ( cx, cy) ] != b'E' {
149+ ns_map[ idx ( cx, cy) ] = ns;
218150
219- let next = d. step ( i ) ;
151+ let next = d. step ( idx ( cx , cy ) ) ;
220152 if s[ next] == b'#' {
221153 for side in d. sides ( ) {
222- let side_i = side. step ( i ) ;
154+ let side_i = side. step ( idx ( cx , cy ) ) ;
223155 if s[ side_i] != b'#' {
224156 d = side;
225157 }
226158 }
227-
228- lines[ d as usize ]
229- . push ( Line {
230- start_ns : ns,
231- line_start : d. select_crosline ( i) ,
232- lien_offset : d. select_inline ( i) ,
233- } )
234- . unwrap ( ) ;
235- quads[ d as usize ] [ qy * QUADS_SIZE + qx]
236- . push ( lines[ d as usize ] . len ( ) - 1 )
237- . unwrap ( ) ;
238-
239- i = d. step ( i) ;
240- } else {
241- i = next;
159+ }
160+ match d {
161+ Dir :: N => cy -= 1 ,
162+ Dir :: E => cx += 1 ,
163+ Dir :: S => cy += 1 ,
164+ Dir :: W => cx -= 1 ,
242165 }
243166 ns += 1 ;
167+
168+ for y in ( cy - 20 ) . max ( 1 ) ..( cy + 21 ) . min ( SIZE as i32 - 1 ) {
169+ for x in
170+ ( -20 + ( y - cy) . abs ( ) + cx) . max ( 1 ) ..( 21 - ( y - cy) . abs ( ) + cx) . min ( SIZE as i32 - 1 )
171+ {
172+ let dist = ( y - cy) . abs ( ) + ( x - cx) . abs ( ) ;
173+ if dist <= 1 {
174+ continue ;
175+ }
176+
177+ let side_i = idx ( x, y) ;
178+ if ns_map[ side_i] != 0 {
179+ let diff = ns - ns_map[ side_i] ;
180+ if diff >= MIN_CHEAT + dist as u16 {
181+ sum += 1 ;
182+ }
183+ }
184+ }
185+ }
244186 }
245187
188+ // for y in 0..SIZE {
189+ // for x in 0..SIZE.min(40) {
190+ // if ns_map[y * SIZE1 + x] != 0 {
191+ // print!("{:^4} ", ns_map[y * SIZE1 + x]);
192+ // } else {
193+ // print!(" . ");
194+ // }
195+ // }
196+ // println!("");
197+ // }
198+ // println!("");
199+
246200 sum
247201}
248202
0 commit comments