Skip to content

Commit dc35a35

Browse files
committed
Day 14; use default hasher and allow integer underflow
1 parent b50ba6f commit dc35a35

File tree

1 file changed

+22
-21
lines changed
  • y23/d14-parabolic-reflector-dish/src

1 file changed

+22
-21
lines changed

y23/d14-parabolic-reflector-dish/src/main.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
use std::hash::{DefaultHasher, Hasher};
2+
13
use aoc::input_str;
24
use itertools::Itertools;
35
use nohash_hasher::IntMap;
46

57
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8+
#[repr(u8)]
69
enum Space {
710
Empty,
811
Square,
@@ -116,10 +119,12 @@ impl Reflector {
116119
for (index, space) in self.get_col(x).enumerate().rev() {
117120
if space.is_round() {
118121
buffer[next_location] = Space::Round;
119-
next_location -= 1;
122+
// Known integer underflow at index 0. However, this is fine
123+
// because we're not going to use the value anyway.
124+
next_location = next_location.wrapping_sub(1);
120125
} else if space.is_square() {
121126
buffer[index] = Space::Square;
122-
next_location = index - 1;
127+
next_location = index.wrapping_sub(1);
123128
}
124129
}
125130

@@ -156,10 +161,12 @@ impl Reflector {
156161
for (index, space) in self.get_row(y).iter().enumerate().rev() {
157162
if space.is_round() {
158163
buffer[next_location] = Space::Round;
159-
next_location -= 1;
164+
// Known integer underflow at index 0. However, this is fine
165+
// because we're not going to use the value anyway.
166+
next_location = next_location.wrapping_sub(1);
160167
} else if space.is_square() {
161168
buffer[index] = Space::Square;
162-
next_location = index - 1;
169+
next_location = index.wrapping_sub(1);
163170
}
164171
}
165172

@@ -182,21 +189,15 @@ impl Reflector {
182189
.sum()
183190
}
184191

185-
/// Calculates the amount of load on the east beam
186-
fn east_load(&self) -> usize {
187-
(0..self.width)
188-
.map(|x| {
189-
(self.width - x)
190-
* (0..self.height)
191-
.filter(|y| self.get(x, *y).is_round())
192-
.count()
193-
})
194-
.sum()
195-
}
192+
fn hash(&self) -> u64 {
193+
let mut hasher = DefaultHasher::new();
196194

197-
/// Uses the north and east loads as a hash
198-
fn load_hash(&self) -> usize {
199-
self.north_load() * self.east_load()
195+
// SAFETY: `Space` is repr(u8), which should mean this is fine
196+
let bytes = unsafe {
197+
std::slice::from_raw_parts(self.spaces.as_ptr() as *const u8, self.spaces.len())
198+
};
199+
hasher.write(bytes);
200+
hasher.finish()
200201
}
201202
}
202203

@@ -219,18 +220,18 @@ fn part2(mut reflector: Reflector) -> usize {
219220
let goal = 1_000_000_000;
220221

221222
let mut seen = IntMap::default();
222-
seen.insert(reflector.load_hash(), 0);
223+
seen.insert(reflector.hash(), 0);
223224

224225
for i in 1.. {
225226
reflector.cycle();
226-
if let Some(&j) = seen.get(&reflector.load_hash()) {
227+
if let Some(&j) = seen.get(&reflector.hash()) {
227228
let remaining = (goal - i) % (i - j);
228229
for _ in 0..remaining {
229230
reflector.cycle();
230231
}
231232
break;
232233
}
233-
seen.insert(reflector.load_hash(), i);
234+
seen.insert(reflector.hash(), i);
234235
}
235236

236237
reflector.north_load()

0 commit comments

Comments
 (0)