Skip to content

Commit af3ff20

Browse files
committed
Use big lut instead of weird shifts
1 parent 50211a9 commit af3ff20

File tree

1 file changed

+58
-27
lines changed

1 file changed

+58
-27
lines changed

src/day8.rs

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,55 @@ const SIZE: i32 = 12;
1010

1111
const SIZE1: i32 = SIZE + 1;
1212

13+
/// Has the `SIZE` lsb set
14+
const FIELD_SIZE: u64 = 2u64.pow(SIZE as u32) - 1;
15+
1316
const 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

Comments
 (0)