diff --git a/benches/benches.rs b/benches/benches.rs index cfa77f5..f1a7b8b 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -175,6 +175,32 @@ fn criterion_benchmark(c: &mut Criterion) { criterion::BatchSize::SmallInput, ) }); + + // Rotation + c.bench_function("grid_rotate_left", |b| { + let grid = init_grid(); + b.iter_batched( + || grid.clone(), + |g| g.rotate_left(), + criterion::BatchSize::SmallInput, + ) + }); + c.bench_function("grid_rotate_right", |b| { + let grid = init_grid(); + b.iter_batched( + || grid.clone(), + |g| g.rotate_right(), + criterion::BatchSize::SmallInput, + ) + }); + c.bench_function("grid_rotate_half", |b| { + let grid = init_grid(); + b.iter_batched( + || grid.clone(), + |g| g.rotate_half(), + criterion::BatchSize::SmallInput, + ) + }); } criterion_group!(benches, criterion_benchmark); diff --git a/src/lib.rs b/src/lib.rs index 234df47..a8608e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -811,6 +811,82 @@ impl Grid { } } + /// Rotate the grid 90° counter-clockwise. + /// + /// # Examples + /// + /// ``` + /// use grid::*; + /// let grid = grid![[1,2,3][4,5,6]]; + /// assert_eq!(grid.rotate_left(), grid![[3,6][2,5][1,4]]); + /// ``` + #[must_use] + pub fn rotate_left(&self) -> Grid + where + T: Clone, + { + let mut data = Vec::with_capacity(self.data.len()); + for c in (0..self.cols).rev() { + for r in 0..self.rows { + data.push(self[r][c].clone()); + } + } + Grid { + data, + cols: self.rows, + rows: self.cols, + } + } + + /// Rotate the grid 90° clockwise. + /// + /// # Examples + /// + /// ``` + /// use grid::*; + /// let grid = grid![[1,2,3][4,5,6]]; + /// assert_eq!(grid.rotate_right(), grid![[4,1][5,2][6,3]]); + /// ``` + #[must_use] + pub fn rotate_right(&self) -> Grid + where + T: Clone, + { + let mut data = Vec::with_capacity(self.data.len()); + for c in 0..self.cols { + for r in (0..self.rows).rev() { + data.push(self[r][c].clone()); + } + } + Grid { + data, + cols: self.rows, + rows: self.cols, + } + } + + /// Rotate the grid 180°. + /// + /// # Examples + /// + /// ``` + /// use grid::*; + /// let grid = grid![[1,2,3][4,5,6]]; + /// assert_eq!(grid.rotate_half(), grid![[6,5,4][3,2,1]]); + /// ``` + #[must_use] + pub fn rotate_half(&self) -> Grid + where + T: Clone, + { + let data: Vec<_> = self.data.iter().rev().cloned().collect(); + Grid { + data, + cols: self.cols, + rows: self.rows, + } + } + /// Fills the grid with elements by cloning `value`. /// /// # Examples