advent-of-code/2022/src/matrix.rs

74 lines
1.8 KiB
Rust

use std::fmt::Debug;
#[derive(Clone, Debug, PartialEq)]
pub struct Matrix<T> {
pub rows: usize,
pub cols: usize,
pub data: Vec<Vec<T>>,
}
impl<T: Clone + Copy + Debug> Matrix<T> {
pub fn new(data: Vec<Vec<T>>) -> Self {
let rows = data.len();
let cols = data
.iter()
.fold(0, |max, row| std::cmp::max(max, row.len()));
Self { rows, cols, data }
}
pub fn row(&self, row_idx: usize) -> Vec<T> {
self.data[row_idx].clone()
}
pub fn col(&self, col_idx: usize) -> Vec<T> {
let mut col = Vec::new();
(0..self.rows).for_each(|row_idx| {
col.push(self.data[row_idx][col_idx]);
});
col
}
pub fn rotate_cw(self) -> Self {
let mut data = Vec::new();
for col_idx in 0..self.cols {
let mut row = vec![];
for row_idx in 0..self.rows {
row.push(self.data[self.rows - row_idx - 1][col_idx]);
}
data.push(row);
}
Self {
rows: self.cols,
cols: self.rows,
data,
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn it_can_rotate_symmetrix_matrix() {
let matrix = Matrix::new(vec![vec!['A', 'B'], vec!['C', 'D']]);
let expected = Matrix::new(vec![vec!['C', 'A'], vec!['D', 'B']]);
assert_eq!(matrix.rotate_cw(), expected);
}
#[test]
fn it_can_rotate_asymmetric_matrix() {
let matrix = Matrix::new(vec![
vec![Some('A'), Some('B'), Some('C')],
vec![Some('D'), Some('E'), Some('F')],
]);
let expected = Matrix::new(vec![
vec![Some('D'), Some('A')],
vec![Some('E'), Some('B')],
vec![Some('F'), Some('C')],
]);
assert_eq!(matrix.rotate_cw(), expected);
}
}