74 lines
1.8 KiB
Rust
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);
|
|
}
|
|
}
|