@@ -15,14 +15,7 @@ pub fn part1(s: &str) -> u64 {
1515
1616#[ inline( always) ]
1717fn 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- // );
18+ // println!("at {:5}, got: {:5} x {}", position, block_id, size);
2619 size as u64 * block_id as u64 * ( 2 * position as u64 + size as u64 - 1 )
2720}
2821
@@ -80,36 +73,72 @@ pub fn part2(s: &str) -> u64 {
8073fn part2_inner ( s : & str ) -> u64 {
8174 let s = s. as_bytes ( ) ;
8275
83- let mut sizes = [ 0 ; INPUT_SIZE ] ;
76+ let mut jump_table: [ usize ; INPUT_SIZE / 2 + 1 ] = const {
77+ let mut t = [ 0 ; INPUT_SIZE / 2 + 1 ] ;
78+ let mut i = 0 ;
79+ while i < INPUT_SIZE / 2 + 1 {
80+ t[ i] = i + 1 ;
81+ i += 1 ;
82+ }
83+ t
84+ } ;
85+
86+ let mut sizes = [ 0 ; INPUT_SIZE / 2 + 1 ] ;
87+ let mut position_table = [ 0 ; INPUT_SIZE / 2 + 1 ] ;
88+ let mut or_position_table = [ 0 ; INPUT_SIZE / 2 + 1 ] ;
89+ let mut position = 0u32 ;
90+ for i in 0 ..INPUT_SIZE / 2 {
91+ sizes[ i + 1 ] = s[ i * 2 + 1 ] - b'0' ;
92+
93+ position += ( s[ i * 2 ] - b'0' ) as u32 ;
94+
95+ position_table[ i + 1 ] = position;
8496
85- for i in 0 ..INPUT_SIZE {
86- sizes[ i] = s[ i] - b'0' ;
97+ position += ( s[ i * 2 + 1 ] - b'0' ) as u32 ;
98+
99+ or_position_table[ i + 1 ] = position;
87100 }
88101
89102 let mut i = INPUT_SIZE - 1 ;
90103
91104 let mut sum = 0 ;
92105 loop {
106+ let hu = i / 2 == 5303 ;
93107 let block_size = s[ i] - b'0' ;
108+ // for i in 0..INPUT_SIZE / 2 + 1 {
109+ // println!(
110+ // "j: {}, p: {}, s: {}",
111+ // jump_table[i], position_table[i], sizes[i]
112+ // );
113+ // }
114+ // dbg!(block_size);
115+
116+ let mut prev_pointer = 0 ;
117+ let mut pointer = jump_table[ 0 ] ;
118+
119+ while pointer * 2 + 1 < i {
120+ if hu {
121+ println ! ( "{pointer}" ) ;
122+ }
123+ let empty_size = sizes[ pointer] ;
94124
95- let mut empty_pointer = 1 ;
96- let mut position = 0 ;
97- while empty_pointer < i {
98- position += sizes[ empty_pointer - 1 ] as u32 ;
99-
100- let empty_size = sizes[ empty_pointer] ;
101125 if empty_size >= block_size {
102- sizes[ empty_pointer as usize ] -= block_size;
103- sizes[ empty_pointer as usize - 1 ] += block_size;
126+ sum += get_checksum ( i / 2 , position_table[ pointer] as u32 , block_size as u32 ) ;
127+
128+ sizes[ pointer] -= block_size;
129+ if sizes[ pointer] == 0 {
130+ jump_table[ prev_pointer] = jump_table[ pointer] ;
131+ }
132+ position_table[ pointer] += block_size as u32 ;
104133
105- sum += get_checksum ( i / 2 , position, block_size as u32 ) ;
106134 break ;
107135 }
108- position += empty_size as u32 ;
109- empty_pointer += 2 ;
136+ prev_pointer = pointer ;
137+ pointer = jump_table [ pointer ] ;
110138 }
111- if empty_pointer >= i {
112- sum += get_checksum ( i / 2 , position, block_size as u32 ) ;
139+ if pointer * 2 + 1 >= i {
140+ // println!("{:?}", or_position_table);
141+ sum += get_checksum ( i / 2 , or_position_table[ i / 2 ] as u32 , block_size as u32 ) ;
113142 }
114143 if i == 0 {
115144 break ;
0 commit comments