pub fn transpose<Outer, Inner, T>(matrix: Outer) -> Vec<Vec<T>>
where
Outer: IntoIterator<Item = Inner>,
Inner: IntoIterator<Item = T>,
{
let mut row_iters: Vec<_> = matrix.into_iter().map(|row| row.into_iter()).collect();
if row_iters.is_empty() {
return vec![];
}
let mut result = Vec::new();
loop {
let mut column: Vec<T> = Vec::new();
let mut has_elements = false;
for row_iter in row_iters.iter_mut() {
if let Some(element) = row_iter.next() {
column.push(element);
has_elements = true;
}
}
if !has_elements {
break;
}
result.push(column);
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_transpose_empty_matrix() {
let matrix: Vec<Vec<i32>> = vec![];
let result = transpose(matrix.clone());
assert_eq!(result, matrix);
}
#[test]
fn test_transpose_empty_rows() {
let matrix: Vec<Vec<i32>> = vec![];
let result = transpose(matrix.clone());
assert_eq!(result, matrix);
}
#[test]
fn test_transpose_single_element() {
let matrix = vec![vec![1]];
let result = transpose(matrix);
assert_eq!(result, vec![vec![1]]);
}
#[test]
fn test_transpose_single_row() {
let matrix = vec![vec![1, 2, 3]];
let result = transpose(matrix);
assert_eq!(result, vec![vec![1], vec![2], vec![3]]);
}
#[test]
fn test_transpose_single_column() {
let matrix = vec![vec![1], vec![2], vec![3]];
let result = transpose(matrix);
assert_eq!(result, vec![vec![1, 2, 3]]);
}
#[test]
fn test_transpose_square_matrix() {
let matrix = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
let result = transpose(matrix);
let expected = vec![vec![1, 4, 7], vec![2, 5, 8], vec![3, 6, 9]];
assert_eq!(result, expected);
}
#[test]
fn test_transpose_rectangular_matrix() {
let matrix = vec![vec![1, 2, 3, 4], vec![5, 6, 7, 8]];
let result = transpose(matrix);
let expected = vec![vec![1, 5], vec![2, 6], vec![3, 7], vec![4, 8]];
assert_eq!(result, expected);
}
#[test]
fn test_transpose_with_strings() {
let matrix = vec![vec!["a", "b"], vec!["c", "d"], vec!["e", "f"]];
let result = transpose(matrix);
let expected = vec![vec!["a", "c", "e"], vec!["b", "d", "f"]];
assert_eq!(result, expected);
}
#[test]
fn test_transpose_double_transpose() {
let matrix = vec![vec![1, 2, 3], vec![4, 5, 6]];
let result = transpose(transpose(matrix.clone()));
assert_eq!(result, matrix);
}
}