Skip to content

Commit 954f153

Browse files
committed
Use bit fields in part 1
1 parent b31db17 commit 954f153

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

src/day8.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,74 +10,77 @@ 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 {
17-
#[expect(unused_unsafe)]
18-
unsafe {
19-
part1_inner(s)
20-
}
19+
pub fn part1(s: &str) -> u32 {
20+
unsafe { part1_inner(s) }
2121
}
2222

23-
fn part1_inner(s: &str) -> u64 {
24-
let s = s.as_bytes();
23+
unsafe fn part1_inner(s: &str) -> u32 {
24+
#[cfg(not(test))]
25+
const SIZE: i16 = 50;
26+
#[cfg(test)]
27+
const SIZE: i16 = 12;
2528

26-
let mut masts: [ArrayVec<[i32; 4]>; FREQ_RANGE] =
27-
[ArrayVec::from_array_empty([0; 4]); FREQ_RANGE];
29+
const SIZE1: i16 = SIZE + 1;
2830

29-
let mut antinodes = [false; (SIZE * SIZE) as usize];
30-
let mut total_antinotedes = 0;
31+
let s = s.as_bytes();
3132

32-
let mut set_node = |x, y| {
33-
total_antinotedes += !antinodes[(y * SIZE + x) as usize] as u64;
34-
antinodes[(y * SIZE + x) as usize] = true;
35-
};
33+
let mut masts: [ArrayVec<[(i16, i16, u64); 3]>; FREQ_RANGE] =
34+
[ArrayVec::from_array_empty([(0, 0, 0); 3]); FREQ_RANGE];
3635

37-
// let mut numbers = [0; 5];
36+
let mut antinodes = [0u64; SIZE as usize];
3837

3938
for i in unsafe { OneInv::new_unchecked(b'.').iter(s) } {
4039
if s[i] == b'\n' {
4140
continue;
4241
}
4342
let f = s[i] - b'0';
44-
let i = i as i32;
43+
let i = i as i16;
4544

4645
let new_x = i % SIZE1;
4746
let new_y = i / SIZE1;
4847

49-
// numbers[masts[f as usize].len()] += 1;
48+
let new_field: u64 = 1 << new_x;
5049

51-
for mast_i in &masts[f as usize] {
52-
let mast_x = mast_i % SIZE1;
53-
let mast_y = mast_i / SIZE1;
50+
// numbers[masts[f as usize].len()] += 1;
5451

52+
for (mast_y, mast_x, mast_field) in masts.get_unchecked(f as usize) {
5553
let diff_x = mast_x - new_x;
56-
let diff_y = (new_y - mast_y).abs() as i32;
54+
let diff_y = new_y - mast_y;
5755

58-
let node_x = mast_x + diff_x;
59-
if node_x >= 0 && node_x < SIZE && mast_y >= diff_y {
56+
if *mast_y >= diff_y {
6057
let node_y = mast_y - diff_y;
6158

62-
set_node(node_x, node_y);
59+
*antinodes.get_unchecked_mut(node_y as usize) |= if diff_x.is_positive() {
60+
mast_field << diff_x
61+
} else {
62+
mast_field >> -diff_x
63+
};
6364
}
6465

65-
let node_x = new_x - diff_x;
66-
if node_x >= 0 && node_x < SIZE && new_y + diff_y < SIZE {
66+
if new_y + diff_y < SIZE {
6767
let node_y = new_y + diff_y;
6868

69-
set_node(node_x, node_y);
69+
*antinodes.get_unchecked_mut(node_y as usize) |= if diff_x.is_positive() {
70+
new_field >> diff_x
71+
} else {
72+
new_field << -diff_x
73+
};
7074
}
7175
}
7276

73-
masts[f as usize].push(i);
77+
masts[f as usize].try_push((new_y, new_x, new_field));
7478
}
7579

76-
// for i in 0..5 {
77-
// println!("{i}: {}", numbers[i]);
78-
// }
79-
80-
total_antinotedes
80+
antinodes
81+
.iter()
82+
.map(|field| (field & FIELD_SIZE).count_ones())
83+
.sum()
8184
}
8285

8386
#[aoc(day8, part2)]

0 commit comments

Comments
 (0)