@@ -148,6 +148,14 @@ pub fn part_two(input: &str) -> Option<u64> {
148148 // 2 pointers again but this time we want to move whole files to the leftmost span of free space blocks that could fit the file
149149 // we want to move the files in order of decreasing file ID number
150150 // if there is no span of free space to the left of a file that is large enough to fit the file, the file does not move
151+
152+ let mut spaces_block_indices: Vec < usize > = Vec :: with_capacity ( 1000 ) ;
153+ for ( i, b) in blocks. iter ( ) . enumerate ( ) {
154+ if b. file_id . is_none ( ) {
155+ spaces_block_indices. push ( i) ;
156+ }
157+ }
158+
151159 let mut right_block_idx = blocks. len ( ) - 1 ;
152160 while right_block_idx > 0 {
153161 let right_block = & blocks[ right_block_idx] ;
@@ -158,18 +166,28 @@ pub fn part_two(input: &str) -> Option<u64> {
158166
159167 // look for a free space block that can fit the file
160168 let mut free_space_block_idx = None ;
161- for i in 0 ..right_block_idx {
162- let left_block = & blocks[ i] ;
163- if left_block. is_free ( ) && left_block. length >= right_block. length {
164- free_space_block_idx = Some ( i) ;
169+ for ( i, space_idx) in spaces_block_indices. iter ( ) . enumerate ( ) {
170+ if * space_idx > right_block_idx {
171+ break ;
172+ }
173+ let left_block = & blocks[ * space_idx] ;
174+ if left_block. length > right_block. length {
175+ free_space_block_idx = Some ( * space_idx) ;
176+ for i in i..spaces_block_indices. len ( ) {
177+ spaces_block_indices[ i] += 1 ;
178+ }
179+ break ;
180+ } else if left_block. length == right_block. length {
181+ free_space_block_idx = Some ( * space_idx) ;
182+ spaces_block_indices. remove ( i) ;
165183 break ;
166184 }
167185 }
168186
169187 if let Some ( left_block_idx) = free_space_block_idx {
170188 let left_block = & blocks[ left_block_idx] ;
171-
172189 let ( _, maybe_left_additional_space) = left_block. split ( right_block. length ) ;
190+
173191 if let Some ( left_additional_space) = maybe_left_additional_space {
174192 blocks. insert ( left_block_idx, right_block. clone ( ) ) ;
175193 blocks[ left_block_idx + 1 ] = left_additional_space;
0 commit comments