diff --git a/src/day18/2.rs b/src/day18/2.rs index 798edfd..2984728 100644 --- a/src/day18/2.rs +++ b/src/day18/2.rs @@ -30,12 +30,21 @@ pub fn run(input: &str) -> (i64, i64) { let mut l = 0; let mut r = bytes.len()-1; + let mut last_set = 0; + while l <= r { let mid = (l + r) / 2; - for b in bytes[0..mid].iter() { - obstacles.set(b.0, b.1); + if last_set > mid { + for b in bytes[mid..last_set].iter() { + obstacles.reset(b.0, b.1); + } + } else { + for b in bytes[last_set..mid].iter() { + obstacles.set(b.0, b.1); + } } + last_set = mid; if dfs(&obstacles, &mut visited, (0,0), (70,70)) { l = mid + 1; @@ -43,7 +52,6 @@ pub fn run(input: &str) -> (i64, i64) { r = mid - 1; } - obstacles.clear(); visited.clear(); } @@ -85,6 +93,7 @@ fn dfs(obstacles: &Bitmap, visited: &mut Bitmap, (x,y): (i64, i64), (ex, ey): (i const WORD_SIZE: usize = 64; +#[derive(Debug, PartialEq, Eq)] struct Bitmap { inner: [u64; (71 * 71) / WORD_SIZE + 1], size: i64, @@ -115,6 +124,16 @@ impl Bitmap { } } + fn reset(&mut self, x: i64, y: i64) { + let offset = (x * self.size + y) as usize; + let index = offset / WORD_SIZE; + let bit_offset = offset % WORD_SIZE; + + unsafe { + *self.inner.get_unchecked_mut(index) &= !(1 << bit_offset); + } + } + fn clear(&mut self) { self.inner.fill(0); }