@@ -5,9 +5,6 @@ const INPUT_SIZE: usize = 19999;
55#[ cfg( test) ]
66const INPUT_SIZE : usize = 19 ;
77
8- // Assume a avrage of 5
9- const MAX_BLOCKS_SIZE : usize = INPUT_SIZE * 5 ;
10-
118#[ aoc( day9, part1) ]
129pub fn part1 ( s : & str ) -> u64 {
1310 #[ expect( unused_unsafe) ]
@@ -18,6 +15,14 @@ pub fn part1(s: &str) -> u64 {
1815
1916#[ inline( always) ]
2017fn get_checksum ( block_id : usize , position : u32 , size : u32 ) -> u64 {
18+ // println!(
19+ // "at {}, got: \"{}\" ({})",
20+ // position,
21+ // std::iter::repeat((block_id as u8 + b'0') as char)
22+ // .take(size as usize)
23+ // .collect::<String>(),
24+ // size
25+ // );
2126 size as u64 * block_id as u64 * ( 2 * position as u64 + size as u64 - 1 )
2227}
2328
@@ -73,65 +78,46 @@ pub fn part2(s: &str) -> u64 {
7378}
7479
7580fn part2_inner ( s : & str ) -> u64 {
76- let input_map = s
77- . as_bytes ( )
78- . strip_suffix ( & [ b'\n' ] )
79- . unwrap_or_else ( || s. as_bytes ( ) ) ;
80-
81- // All blocks with their id, and empty space
82- let mut full_input_blocks: [ u32 ; MAX_BLOCKS_SIZE ] = [ 0 ; MAX_BLOCKS_SIZE ] ;
83- // Like full but without empty space
84- let mut input_blocks: [ ( usize , u32 ) ; INPUT_SIZE / 2 + 1 ] = [ ( 0 , 0 ) ; INPUT_SIZE / 2 + 1 ] ;
85-
86- let mut block_id = 0 ;
87- let mut full_input_blocks_i: usize = 0 ;
88- let mut input_blocks_i: usize = 0 ;
81+ let s = s. as_bytes ( ) ;
8982
90- for c in input_map. chunks ( 2 ) {
91- let block_size = ( c[ 0 ] - b'0' ) as usize ;
83+ let mut sizes = [ 0 ; INPUT_SIZE ] ;
9284
93- full_input_blocks[ full_input_blocks_i..full_input_blocks_i + block_size] . fill ( block_id) ;
85+ for i in 0 ..INPUT_SIZE {
86+ sizes[ i] = s[ i] - b'0' ;
87+ }
9488
95- input_blocks [ input_blocks_i ] = ( full_input_blocks_i , block_size as u32 ) ;
89+ let mut i = INPUT_SIZE - 1 ;
9690
97- full_input_blocks_i += block_size;
98- input_blocks_i += 1 ;
91+ let mut sum = 0 ;
92+ loop {
93+ let block_size = s[ i] - b'0' ;
9994
100- if c . len ( ) == 2 {
101- let empty_size = ( c [ 1 ] - b'0' ) as usize ;
102- full_input_blocks_i += empty_size ;
103- }
95+ let mut empty_pointer = 1 ;
96+ let mut position = 0 ;
97+ while empty_pointer < i {
98+ position += sizes [ empty_pointer - 1 ] as u32 ;
10499
105- block_id += 1 ;
106- }
100+ let empty_size = sizes[ empty_pointer] ;
101+ if empty_size >= block_size {
102+ sizes[ empty_pointer as usize ] -= block_size;
103+ sizes[ empty_pointer as usize - 1 ] += block_size;
107104
108- let full_input_blocks_start: usize = ( input_map[ 0 ] - b'0' ) as usize ;
109-
110- for block_id in ( 1 ..input_blocks_i) . rev ( ) {
111- let ( position, size) = input_blocks[ block_id] ;
112-
113- let mut i = full_input_blocks_start;
114- let mut search_size = 0 ;
115- while i < position {
116- if full_input_blocks[ i as usize ] == 0 {
117- search_size += 1 ;
118- if search_size == size {
119- full_input_blocks[ position..position + size as usize ] . fill ( 0 ) ;
120- full_input_blocks[ i - size as usize + 1 ..i + 1 ] . fill ( block_id as u32 ) ;
121- break ;
122- }
123- } else {
124- search_size = 0 ;
105+ sum += get_checksum ( i / 2 , position, block_size as u32 ) ;
106+ break ;
125107 }
126- i += 1 ;
108+ position += empty_size as u32 ;
109+ empty_pointer += 2 ;
110+ }
111+ if empty_pointer >= i {
112+ sum += get_checksum ( i / 2 , position, block_size as u32 ) ;
127113 }
114+ if i == 0 {
115+ break ;
116+ }
117+ i -= 2 ;
128118 }
129119
130- full_input_blocks
131- . iter ( )
132- . enumerate ( )
133- . map ( |( i, id) | i as u64 * * id as u64 )
134- . sum ( )
120+ sum / 2
135121}
136122
137123#[ cfg( test) ]
@@ -151,3 +137,14 @@ mod tests {
151137 assert_eq ! ( part2( EXAMPLE ) , 2858 ) ;
152138 }
153139}
140+
141+ // at 00, got: "00" (2)
142+ // at 02, got: "99" (2)
143+ // at 04, got: "2" (1)
144+ // at 05, got: "111" (3)
145+ // at 08, got: "777" (3)
146+ // at 12, got: "44" (2)
147+ // at 15, got: "333" (3)
148+ // at 22, got: "5555" (4)
149+ // at 27, got: "6666" (4)
150+ // at 36, got: "8888" (4)
0 commit comments