use std::path::Path; // Yoinked from https://github.com/loafey/advent_of_code/blob/master/utils/lib.rs pub fn load_string>(p: P) -> String { std::fs::read_to_string(&p).unwrap_or_else(|_| panic!("failed to load {:?}", p.as_ref())) } pub trait Matrix { fn transpose(self) -> Self; fn reverse_rows(self) -> Self; fn rotate_counter_clockwise(self) -> Self; } impl Matrix for Vec> { // Yes, very inefficient // Easy peasy when fn transpose(self) -> Self { let mut o: Vec>> = vec![vec![None; self.len()]; self.first().unwrap().len()]; self.into_iter().enumerate().for_each(|(y, l)| { l.into_iter().enumerate().for_each(|(x, e)| { o[x][y] = Some(e); }) }); o.into_iter() .map(|r| r.into_iter().map(|e| e.unwrap()).collect()) .collect() } fn reverse_rows(self) -> Self { let mut o = self.clone(); o.reverse(); o } fn rotate_counter_clockwise(self) -> Self { self.transpose().reverse_rows() } } #[cfg(test)] mod tests { use super::*; #[test] fn test_transpose() { let x = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]; let result = vec![vec![1, 4, 7], vec![2, 5, 8], vec![3, 6, 9]]; assert_eq!(x.transpose(), result); } #[test] fn test_rotate_counter_clockwise() { let x = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]]; let result = vec![vec![3, 6, 9], vec![2, 5, 8], vec![1, 4, 7]]; assert_eq!(x.rotate_counter_clockwise(), result); } }