@@ -10,29 +10,55 @@ const SIZE: i32 = 12;
1010
1111const SIZE1 : i32 = SIZE + 1 ;
1212
13+ /// Has the `SIZE` lsb set
14+ const FIELD_SIZE : u64 = 2u64 . pow ( SIZE as u32 ) - 1 ;
15+
1316const FREQ_RANGE : usize = ( b'z' - b'0' + 1 ) as usize ;
1417
1518#[ aoc( day8, part1) ]
16- pub fn part1 ( s : & str ) -> u64 {
19+ pub fn part1 ( s : & str ) -> u32 {
1720 unsafe { part1_inner ( s) }
1821}
1922
20- unsafe fn part1_inner ( s : & str ) -> u64 {
23+ const SHIFT_LUT : [ u64 ; ( SIZE * SIZE * 2 ) as usize ] = {
24+ let mut lut = [ 0 ; ( SIZE * SIZE * 2 ) as usize ] ;
25+
26+ let mut x = 0 ;
27+ while x < SIZE {
28+ let mut diff_x = -SIZE + 1 ;
29+
30+ let field = 1 << x;
31+
32+ while diff_x < SIZE {
33+ lut[ ( x * SIZE * 2 + diff_x + SIZE - 1 ) as usize ] = if diff_x. is_positive ( ) {
34+ field << diff_x
35+ } else {
36+ field >> -diff_x
37+ } ;
38+
39+ diff_x += 1 ;
40+ }
41+
42+ x += 1 ;
43+ }
44+
45+ lut
46+ } ;
47+
48+ unsafe fn part1_inner ( s : & str ) -> u32 {
2149 #[ cfg( not( test) ) ]
2250 const SIZE : i16 = 50 ;
2351 #[ cfg( test) ]
2452 const SIZE : i16 = 12 ;
2553
2654 const SIZE1 : i16 = SIZE + 1 ;
55+
2756 let s = s. as_bytes ( ) ;
2857
29- let mut masts: [ ArrayVec < [ i16 ; 3 ] > ; FREQ_RANGE ] =
30- [ ArrayVec :: from_array_empty ( [ 0 ; 3 ] ) ; FREQ_RANGE ] ;
58+ let mut masts: [ ArrayVec < [ ( i16 , i16 ) ; 3 ] > ; FREQ_RANGE ] =
59+ [ ArrayVec :: from_array_empty ( [ ( 0 , 0 ) ; 3 ] ) ; FREQ_RANGE ] ;
3160
32- let mut antinodes = [ false ; ( SIZE * SIZE ) as usize ] ;
33- let mut total_antinotedes = 0 ;
34-
35- // let mut numbers = [0; 5];
61+ let mut antinodes = [ 0u64 ; SIZE as usize ] ;
3662
3763 for i in unsafe { OneInv :: new_unchecked ( b'.' ) . iter ( s) } {
3864 if s[ i] == b'\n' {
@@ -46,40 +72,45 @@ unsafe fn part1_inner(s: &str) -> u64 {
4672
4773 // numbers[masts[f as usize].len()] += 1;
4874
49- for mast_i in & masts[ f as usize ] {
50- let mast_x = mast_i % SIZE1 ;
51- let mast_y = mast_i / SIZE1 ;
52-
75+ for ( mast_y, mast_x) in masts. get_unchecked ( f as usize ) {
5376 let diff_x = mast_x - new_x;
5477 let diff_y = new_y - mast_y;
5578
56- let node_x = mast_x + diff_x;
57- if node_x >= 0 && node_x < SIZE && mast_y >= diff_y {
79+ if * mast_y >= diff_y {
5880 let node_y = mast_y - diff_y;
5981
60- total_antinotedes +=
61- !antinodes. get_unchecked ( ( node_y * SIZE + node_x) as usize ) as u64 ;
62- * antinodes. get_unchecked_mut ( ( node_y * SIZE + node_x) as usize ) = true ;
82+ * antinodes. get_unchecked_mut ( node_y as usize ) |=
83+ SHIFT_LUT [ ( mast_x * SIZE * 2 + diff_x + SIZE - 1 ) as usize ] ;
6384 }
6485
65- let node_x = new_x - diff_x;
66- if node_x >= 0 && node_x < SIZE && new_y + diff_y < SIZE {
86+ if new_y + diff_y < SIZE {
6787 let node_y = new_y + diff_y;
6888
69- total_antinotedes +=
70- !antinodes. get_unchecked ( ( node_y * SIZE + node_x) as usize ) as u64 ;
71- * antinodes. get_unchecked_mut ( ( node_y * SIZE + node_x) as usize ) = true ;
89+ * antinodes. get_unchecked_mut ( node_y as usize ) |=
90+ SHIFT_LUT [ ( new_x * SIZE * 2 - diff_x + SIZE - 1 ) as usize ] ;
7291 }
7392 }
7493
75- masts[ f as usize ] . try_push ( i ) ;
94+ masts[ f as usize ] . try_push ( ( new_y , new_x ) ) ;
7695 }
77-
78- // for i in 0..5 {
79- // println!("{i}: {}", numbers[i]);
96+ // for y in 0..SIZE {
97+ // for x in 0..SIZE {
98+ // print!(
99+ // "{}",
100+ // if antinodes[y as usize] & 1 << x != 0 {
101+ // '#'
102+ // } else {
103+ // s[(y * SIZE1 + x) as usize] as char
104+ // }
105+ // )
106+ // }
107+ // println!("");
80108 // }
81109
82- total_antinotedes
110+ antinodes
111+ . iter ( )
112+ . map ( |field| ( field & FIELD_SIZE ) . count_ones ( ) )
113+ . sum ( )
83114}
84115
85116#[ aoc( day8, part2) ]
0 commit comments