diff --git a/src/bin/2022_08/main.rs b/src/bin/2022_08/main.rs index 8815b9d..2f3de00 100644 --- a/src/bin/2022_08/main.rs +++ b/src/bin/2022_08/main.rs @@ -59,15 +59,15 @@ fn part1(grid: &Grid) -> usize { fn part2(grid: &Grid) -> i32 { let mut ans = 0; - for (i, j) in iproduct!(0..grid.rows, 0..grid.cols) { + for idx in iproduct!(0..grid.rows, 0..grid.cols) { let mut scores = [0; 4]; - let sweeps = grid.sweep_4(i, j); - let h = grid.get(&(i, j)); + let sweeps = grid.sweep_4(&idx); + let h = grid.get(&idx); - for (idx, sweep) in sweeps.iter().enumerate() { + for (i, sweep) in sweeps.iter().enumerate() { for nxy in sweep { let h1 = grid.get(nxy); - scores[idx] += 1; + scores[i] += 1; if h1 >= h { break; diff --git a/src/bin/2022_12/main.rs b/src/bin/2022_12/main.rs index 294820b..f1e77a3 100644 --- a/src/bin/2022_12/main.rs +++ b/src/bin/2022_12/main.rs @@ -38,7 +38,7 @@ fn shortest_from(grid: &Grid, start: (usize, usize), end: (usize, usize)) visited.set(&elem, true); let val = grid.get(&elem); - let adjacent = grid.adjacent_4(elem.0, elem.1); + let adjacent = grid.adjacent_4(&elem); let next_cells = adjacent .iter() .filter(|&e| grid.get(e) <= val + 1) diff --git a/src/bin/2023_03/main.rs b/src/bin/2023_03/main.rs index 8da573f..cf6b140 100644 --- a/src/bin/2023_03/main.rs +++ b/src/bin/2023_03/main.rs @@ -32,10 +32,11 @@ fn solve(input: &str) -> u32 { let mut neighboring_symbols: Vec<(char, usize)> = Vec::new(); for j in 0..grid.cols { - let ch = grid.get(&(i, j)); + let idx = (i, j); + let ch = grid.get(&idx); if ch.is_ascii_digit() { num = 10 * num + ch.to_digit(10).unwrap(); - let ncells = grid.adjacent_8(i, j); + let ncells = grid.adjacent_8(&idx); for nidx in &ncells { let ch1 = grid.get(nidx); if symbols.contains(&ch1) { @@ -49,9 +50,9 @@ fn solve(input: &str) -> u32 { neighboring_symbols = neighboring_symbols.into_iter().unique().collect::>(); - for (ch, idx) in &neighboring_symbols { + for (ch, key) in &neighboring_symbols { if *ch == '*' { - part_numbers_map.add_to_vector_hashmap(idx, num); + part_numbers_map.add_to_vector_hashmap(key, num); } } diff --git a/src/bin/2023_10/main.rs b/src/bin/2023_10/main.rs index 8495c67..80c2df3 100644 --- a/src/bin/2023_10/main.rs +++ b/src/bin/2023_10/main.rs @@ -157,25 +157,25 @@ fn solve(input: &str) -> usize { let mut path = Vec::new(); let mut half_path2 = Vec::new(); - for (i, j) in iproduct!(0..grid.rows, 0..grid.cols) { - if grid.get(&(i, j)).len() == 4 { + for idx in iproduct!(0..grid.rows, 0..grid.cols) { + if grid.get(&idx).len() == 4 { // Add start to path - path.push((i, j)); + path.push(idx); let mut queue = VecDeque::<(CellIndex, bool)>::new(); - let nbs = grid.adjacent_4(i, j); - for idx in &nbs { - let ndirs = grid.get(idx); - let nns = grid.adjacent_in_dir(idx.0, idx.1, &ndirs); - if nns.contains(&(i, j)) { - queue.push_back((*idx, d)); + let nbs = grid.adjacent_4(&idx); + for nidx in &nbs { + let ndirs = grid.get(nidx); + let nns = grid.adjacent_in_dir(nidx, &ndirs); + if nns.contains(&idx) { + queue.push_back((*nidx, d)); d = !d; } } assert!(queue.len() == 2); - visited.set(&(i, j), true); + visited.set(&idx, true); while !queue.is_empty() { let (cidx, lr) = queue.pop_front().unwrap(); if lr { @@ -186,7 +186,7 @@ fn solve(input: &str) -> usize { visited.set(&cidx, true); let dirs = grid.get(&cidx); - let nc = grid.adjacent_in_dir(cidx.0, cidx.1, &dirs); + let nc = grid.adjacent_in_dir(&cidx, &dirs); for nidx in &nc { if !visited.get(nidx) { queue.push_back((*nidx, lr)); @@ -214,12 +214,12 @@ fn solve(input: &str) -> usize { for (dir, p) in directed_path.iter().zip(path.iter()) { let (l, r) = lr_classification(original.get(p), dir); - for idx in cluster.adjacent_in_dir(p.0, p.1, &l) { + for idx in cluster.adjacent_in_dir(p, &l) { if cluster.get(&idx) == Cluster::Empty { cluster.set(&idx, Cluster::Side1); } } - for idx in cluster.adjacent_in_dir(p.0, p.1, &r) { + for idx in cluster.adjacent_in_dir(p, &r) { if cluster.get(&idx) == Cluster::Empty { cluster.set(&idx, Cluster::Side2); } diff --git a/src/bin/2023_16/main.rs b/src/bin/2023_16/main.rs index 98843b8..05276c8 100644 --- a/src/bin/2023_16/main.rs +++ b/src/bin/2023_16/main.rs @@ -44,7 +44,7 @@ fn solve(grid: &Grid, start: CellIndex, start_dir: CellDir) -> usize { }; for nd in &next_dirs { - if let Some(nc) = grid.cell_in_direction(cell_idx.0, cell_idx.1, nd.0, nd.1) { + if let Some(nc) = grid.cell_in_direction(&cell_idx, nd) { queue.push_back((nc, *nd)); } } diff --git a/src/bin/2023_17/main.rs b/src/bin/2023_17/main.rs index e157504..90664c7 100644 --- a/src/bin/2023_17/main.rs +++ b/src/bin/2023_17/main.rs @@ -17,7 +17,7 @@ fn add_neighbor_in_cardinal_dir( hops: usize, ) { let dir = cardinal_dir.to_dir(); - let opt_neighbor = g.cell_in_direction(cell_index.0, cell_index.1, dir.0, dir.1); + let opt_neighbor = g.cell_in_direction(cell_index, &dir); if let Some(neighbor) = opt_neighbor { ret.push(((neighbor, *cardinal_dir, hops), g.get(&neighbor))); diff --git a/src/bin/2023_23/main.rs b/src/bin/2023_23/main.rs index d1c3520..23af5b4 100644 --- a/src/bin/2023_23/main.rs +++ b/src/bin/2023_23/main.rs @@ -17,16 +17,16 @@ enum Cell { fn get_neighbors(g: &Grid, lst: &CellIndex, slopes: bool) -> Vec { match g.get(lst) { Cell::Path => g - .adjacent_4(lst.0, lst.1) + .adjacent_4(lst) .into_iter() .filter(|idx| g.get(idx) != Cell::Forest) .collect::>(), Cell::Slope(cd) => { if slopes { let dir = cd.to_dir(); - vec![g.cell_in_direction(lst.0, lst.1, dir.0, dir.1).unwrap()] + vec![g.cell_in_direction(lst, &dir).unwrap()] } else { - g.adjacent_4(lst.0, lst.1) + g.adjacent_4(lst) .into_iter() .filter(|idx| g.get(idx) != Cell::Forest) .collect::>() diff --git a/src/grid.rs b/src/grid.rs index 0dbc539..72f41f9 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -186,7 +186,7 @@ impl Grid { idx.0 * self.cols + idx.1 } - pub fn from_flat_idx(&self, idx: usize) -> (usize, usize) { + pub fn from_flat_idx(&self, idx: usize) -> CellIndex { (idx / self.cols, idx % self.cols) } @@ -208,40 +208,24 @@ impl Grid { self.values[idx.0][idx.1] = val; } - pub fn cell_in_direction( - &self, - i: usize, - j: usize, - di: i32, - dj: i32, - ) -> Option<(usize, usize)> { - let mut x = i as i32; - let mut y = j as i32; - let mut found = false; - if ((di < 0 && x + di >= 0) || (di >= 0 && x + di < self.rows as i32)) - && ((dj < 0 && y + dj >= 0) || (dj >= 0 && y + dj < self.cols as i32)) + pub fn cell_in_direction(&self, idx: &CellIndex, dir: &CellDir) -> Option<(usize, usize)> { + let x = idx.0 as i32; + let y = idx.1 as i32; + let dx = dir.0; + let dy = dir.1; + if ((dx < 0 && x + dx >= 0) || (dx >= 0 && x + dx < self.rows as i32)) + && ((dy < 0 && y + dy >= 0) || (dy >= 0 && y + dy < self.cols as i32)) { - x += di; - y += dj; - found = true; - } - - if found { - return Some((x as usize, y as usize)); + return Some(((x + dx) as usize, (y + dy) as usize)); } None } - pub fn adjacent_in_dir( - &self, - i: usize, - j: usize, - dirs: &Vec<(i32, i32)>, - ) -> Vec<(usize, usize)> { + pub fn adjacent_in_dir(&self, idx: &CellIndex, dirs: &Vec<(i32, i32)>) -> Vec<(usize, usize)> { let mut ret = Vec::new(); for d in dirs { - let opt_cell = self.cell_in_direction(i, j, d.0, d.1); + let opt_cell = self.cell_in_direction(idx, d); if let Some(cell) = opt_cell { ret.push(cell); } @@ -249,18 +233,17 @@ impl Grid { ret } - pub fn adjacent_2_row(&self, i: usize, j: usize) -> Vec<(usize, usize)> { - self.adjacent_in_dir(i, j, &vec![(0, 1), (0, -1)]) + pub fn adjacent_2_row(&self, idx: &CellIndex) -> Vec<(usize, usize)> { + self.adjacent_in_dir(idx, &vec![(0, 1), (0, -1)]) } - pub fn adjacent_4(&self, i: usize, j: usize) -> Vec<(usize, usize)> { - self.adjacent_in_dir(i, j, &vec![(-1, 0), (0, -1), (1, 0), (0, 1)]) + pub fn adjacent_4(&self, idx: &CellIndex) -> Vec<(usize, usize)> { + self.adjacent_in_dir(idx, &vec![(-1, 0), (0, -1), (1, 0), (0, 1)]) } - pub fn adjacent_8(&self, i: usize, j: usize) -> Vec<(usize, usize)> { + pub fn adjacent_8(&self, idx: &CellIndex) -> Vec<(usize, usize)> { self.adjacent_in_dir( - i, - j, + idx, &vec![ (-1, 0), (0, -1), @@ -274,22 +257,15 @@ impl Grid { ) } - pub fn sweep_4(&self, i: usize, j: usize) -> [Vec<(usize, usize)>; 4] { + pub fn sweep_4(&self, idx: &CellIndex) -> [Vec<(usize, usize)>; 4] { const VAL: Vec<(usize, usize)> = vec![]; let mut ret: [Vec<(usize, usize)>; 4] = [VAL; 4]; let dir = [(-1, 0), (0, -1), (1, 0), (0, 1)]; - for (idx, d) in dir.iter().enumerate() { - let mut x = i; - let mut y = j; - loop { - let cell = self.cell_in_direction(x, y, d.0, d.1); - if cell.is_none() { - break; - } - let cell = cell.unwrap(); - x = cell.0; - y = cell.1; - ret[idx].push(cell); + for (i, d) in dir.iter().enumerate() { + let mut curr_cell = *idx; + while let Some(cell) = self.cell_in_direction(&curr_cell, d) { + ret[i].push(cell); + curr_cell = cell; } } ret @@ -317,7 +293,7 @@ impl Grid { self.set(&x, cluster_id.clone()); - for n in self.adjacent_4(x.0, x.1) { + for n in self.adjacent_4(&x) { if self.get(&n) == replace_id.clone() { q.push_back(n); } @@ -337,26 +313,26 @@ mod tests { assert!(grid.rows == 10); assert!(grid.cols == 6); - let c1 = grid.cell_in_direction(0, 0, -1, 0); + let c1 = grid.cell_in_direction(&(0, 0), &(-1, 0)); assert!(c1.is_none()); - let c2 = grid.cell_in_direction(0, 0, 1, 0); + let c2 = grid.cell_in_direction(&(0, 0), &(1, 0)); assert!(c2.is_some()); assert!(c2.unwrap() == (1, 0)); - let nxy = grid.adjacent_4(0, 0); + let nxy = grid.adjacent_4(&(0, 0)); assert!(nxy == vec![(1, 0), (0, 1)]); - let nxy = grid.adjacent_4(2, 4); + let nxy = grid.adjacent_4(&(2, 4)); assert!(nxy == vec![(1, 4), (2, 3), (3, 4), (2, 5)]); - let sxy = grid.sweep_4(2, 4); + let sxy = grid.sweep_4(&(2, 4)); assert!(sxy[0] == vec![(1, 4), (0, 4)]); assert!(sxy[1] == vec![(2, 3), (2, 2), (2, 1), (2, 0)]); assert!(sxy[2] == vec![(3, 4), (4, 4), (5, 4), (6, 4), (7, 4), (8, 4), (9, 4)]); assert!(sxy[3] == vec![(2, 5)]); - let nxy = grid.adjacent_8(0, 0); + let nxy = grid.adjacent_8(&(0, 0)); assert!(nxy == vec![(1, 0), (0, 1), (1, 1)]); } }