retroactive, to derust my rust
at main 95 lines 2.7 kB view raw
1use std::collections::BTreeSet; 2 3use itertools::Itertools; 4 5#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 6pub struct Point { 7 pub row: usize, 8 pub col: usize, 9} 10 11pub fn all_coords(width: usize, height: usize) -> impl Iterator<Item = Point> { 12 (0..height) 13 .cartesian_product(0..width) 14 .map(|(row, col)| Point { row, col }) 15} 16 17///Never Eat Shredded Wheat 18pub fn adjacent_cardinal<T: Copy>(grid: &[Vec<T>], coords: Point) -> [Option<T>; 4] { 19 let mut retval = [const { None }; 4]; 20 let (row, col) = (coords.row, coords.col); 21 22 if row > 0 { 23 retval[0] = Some(grid[row - 1][col]) //N 24 } 25 if col < grid[0].len() - 1 { 26 retval[1] = Some(grid[row][col + 1]) //E 27 } 28 if row < grid.len() - 1 { 29 retval[2] = Some(grid[row + 1][col]) //S 30 } 31 if col > 0 { 32 retval[3] = Some(grid[row][col - 1]) //N 33 } 34 35 retval 36} 37 38pub fn adjacent_cardinal_points<T: Copy>(grid: &[Vec<T>], coords: Point) -> Vec<Point> { 39 let mut retval = vec![]; 40 let (row, col) = (coords.row, coords.col); 41 42 if row > 0 { 43 retval.push(Point { row: row - 1, col }) //N 44 } 45 if col < grid[0].len() - 1 { 46 retval.push(Point { row, col: col + 1 }) //E 47 } 48 if row < grid.len() - 1 { 49 retval.push(Point { row: row + 1, col }) //S 50 } 51 if col > 0 { 52 retval.push(Point { row, col: col - 1 }) //W 53 } 54 55 retval 56} 57 58//2d spatial digraph 59pub fn flood(digraph: &[Vec<Vec<Point>>], start: Point) -> BTreeSet<Point> { 60 let mut reachable = BTreeSet::new(); 61 let mut frontier = BTreeSet::from_iter([start]); 62 63 while let Some(cursor) = frontier.pop_first() { 64 reachable.insert(cursor); 65 let next = BTreeSet::from_iter(digraph[cursor.row][cursor.col].iter().cloned()); 66 for &point in next.difference(&reachable) { 67 frontier.insert(point); 68 } 69 } 70 71 reachable 72} 73 74//2d spatial dag 75pub fn paths_to_each_point( 76 digraph: &[Vec<Vec<Point>>], 77 start: Point, 78) -> Vec<Vec<BTreeSet<Vec<Point>>>> { 79 let mut paths_to_each_point = vec![vec![BTreeSet::new(); digraph.len()]; digraph[0].len()]; 80 paths_to_each_point[start.row][start.col] = BTreeSet::from_iter([vec![start]]); 81 let mut frontier = BTreeSet::from_iter([start]); 82 83 while let Some(cursor) = frontier.pop_first() { 84 for point in &digraph[cursor.row][cursor.col] { 85 frontier.insert(*point); 86 let paths_to_new_point = paths_to_each_point[cursor.row][cursor.col].clone(); 87 for mut path in paths_to_new_point { 88 path.push(*point); 89 paths_to_each_point[point.row][point.col].insert(path); 90 } 91 } 92 } 93 94 paths_to_each_point 95}