diff --git a/src/day6.rs b/src/day6.rs index bf990b1..5567ad7 100644 --- a/src/day6.rs +++ b/src/day6.rs @@ -1,5 +1,7 @@ type Input = ((usize, usize), Vec>); +use std::collections::HashSet; + use aoc_runner_derive::{aoc, aoc_generator}; #[aoc_generator(day6)] fn parse(input: &str) -> Input { @@ -98,7 +100,7 @@ fn part2(input: &Input) -> u64 { ); if map[next_pos.1][next_pos.0] != 1 { map[next_pos.1][next_pos.0] = 1; - if check_loop(initial, (0, -1), &map) { + if check_loop(pos, dir, &map) { // count += 1; if !(loops.contains(&next_pos)) && next_pos != initial { loops.push(next_pos); @@ -112,12 +114,22 @@ fn part2(input: &Input) -> u64 { loops.len() as u64 } -fn check_loop(pos: (usize, usize), dir: (isize, isize), map: &[Vec]) -> bool { - let mut visited = vec![]; +static mut VISITED: [[[bool; 4]; 130]; 130] = [[[false; 4]; 130]; 130]; +static mut VISITED_VEC: Vec<(usize, usize, usize)> = vec![]; +fn check_loop(pos: (usize, usize), dir: (isize, isize), map: &[Vec]) -> bool { let h = map.len(); let w = map[0].len(); + unsafe { + VISITED_VEC.clear(); + VISITED_VEC.reserve(w * h * 4); + } + + // let mut visited = [[[false; 4]; 130]; 130]; + // let mut visited = HashSet::with_capacity(h * w * 4); + // let mut visited = 0; + let mut dir = dir; let mut pos = pos; @@ -143,20 +155,37 @@ fn check_loop(pos: (usize, usize), dir: (isize, isize), map: &[Vec]) -> bool turns += 1; } + if turns == 2 { + break; + } pos = ( (pos.0 as isize + dir.0) as usize, (pos.1 as isize + dir.1) as usize, ); - if visited.contains(&(pos.0, pos.1, dir.0, dir.1)) { - return true; - } else if turns > 0 { - visited.push((pos.0, pos.1, dir.0, dir.1)); + let dirnum = ((dir.1 + 1) >> 2) as usize + (dir.0 + 1) as usize; + unsafe { + if VISITED[pos.1][pos.0][dirnum] { + clear_visited(); + return true; + } else if turns > 0 { + VISITED[pos.1][pos.0][dirnum] = true; + VISITED_VEC.push((pos.0, pos.1, dirnum)); + } } } + unsafe { + clear_visited(); + } + false } +unsafe fn clear_visited() { + VISITED_VEC + .iter() + .for_each(|(a, b, c)| VISITED[*b][*a][*c] = false); +} #[cfg(test)] mod tests { use super::*;