Skip to content

Commit

Permalink
cell index
Browse files Browse the repository at this point in the history
  • Loading branch information
hsaikia committed Dec 27, 2023
1 parent 36d8803 commit 3463935
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 82 deletions.
10 changes: 5 additions & 5 deletions src/bin/2022_08/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ fn part1(grid: &Grid<u32>) -> usize {
fn part2(grid: &Grid<u32>) -> 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;
Expand Down
2 changes: 1 addition & 1 deletion src/bin/2022_12/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn shortest_from(grid: &Grid<usize>, 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)
Expand Down
9 changes: 5 additions & 4 deletions src/bin/2023_03/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ fn solve<const PART1: bool>(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) {
Expand All @@ -49,9 +50,9 @@ fn solve<const PART1: bool>(input: &str) -> u32 {
neighboring_symbols =
neighboring_symbols.into_iter().unique().collect::<Vec<_>>();

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);
}
}

Expand Down
26 changes: 13 additions & 13 deletions src/bin/2023_10/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,25 +157,25 @@ fn solve<const PART1: bool>(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 {
Expand All @@ -186,7 +186,7 @@ fn solve<const PART1: bool>(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));
Expand Down Expand Up @@ -214,12 +214,12 @@ fn solve<const PART1: bool>(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);
}
Expand Down
2 changes: 1 addition & 1 deletion src/bin/2023_16/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn solve(grid: &Grid<char>, 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));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/bin/2023_17/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down
6 changes: 3 additions & 3 deletions src/bin/2023_23/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ enum Cell {
fn get_neighbors(g: &Grid<Cell>, lst: &CellIndex, slopes: bool) -> Vec<CellIndex> {
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::<Vec<_>>(),
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::<Vec<_>>()
Expand Down
84 changes: 30 additions & 54 deletions src/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ impl<T: std::fmt::Debug + Clone + Default + PartialEq + Hash> Grid<T> {
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)
}

Expand All @@ -208,59 +208,42 @@ impl<T: std::fmt::Debug + Clone + Default + PartialEq + Hash> Grid<T> {
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);
}
}
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),
Expand All @@ -274,22 +257,15 @@ impl<T: std::fmt::Debug + Clone + Default + PartialEq + Hash> Grid<T> {
)
}

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
Expand Down Expand Up @@ -317,7 +293,7 @@ impl<T: std::fmt::Debug + Clone + Default + PartialEq + Hash> Grid<T> {

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);
}
Expand All @@ -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)]);
}
}

0 comments on commit 3463935

Please sign in to comment.