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