Challenge 63
Number Spiral
Given a positive integer n, generate an n x n spiral matrix filled with numbers from 1 to n² in a clockwise spiral pattern, starting from the top-left corner.
Your function generate_spiral
should return the matrix as a vector of vectors.
The spiral moves right, down, left, and up, filling the matrix layer by layer.
assert_eq!(generate_spiral(0), Vec::<Vec<i32>>::new()); assert_eq!(generate_spiral(1), vec![vec![1]]); assert_eq!(generate_spiral(3), vec![vec![1, 2, 3], vec![8, 9, 4], vec![7, 6, 5]]); assert_eq!( generate_spiral(5), vec![ vec![1, 2, 3, 4, 5], vec![16, 17, 18, 19, 6], vec![15, 24, 25, 20, 7], vec![14, 23, 22, 21, 8], vec![13, 12, 11, 10, 9] ] );
Write your solution below
// Rust Bytes Issue 72: Number Spiral pub fn generate_spiral(n: i32) -> Vec<Vec<i32>> { // your implementation goes here } #[cfg(test)] mod tests { use super::*; #[test] fn test_n_1() { assert_eq!(generate_spiral(1), vec![vec![1]]); } #[test] fn test_n_2() { assert_eq!(generate_spiral(2), vec![vec![1, 2], vec![4, 3]]); } #[test] fn test_n_3() { assert_eq!( generate_spiral(3), vec![vec![1, 2, 3], vec![8, 9, 4], vec![7, 6, 5]] ); } #[test] fn test_n_0() { assert_eq!(generate_spiral(0), Vec::<Vec<i32>>::new()); } #[test] fn test_n_negative() { assert_eq!(generate_spiral(-1), Vec::<Vec<i32>>::new()); } #[test] fn test_n_4() { assert_eq!( generate_spiral(4), vec![ vec![1, 2, 3, 4], vec![12, 13, 14, 5], vec![11, 16, 15, 6], vec![10, 9, 8, 7] ] ); } #[test] fn test_n_5() { assert_eq!( generate_spiral(5), vec![ vec![1, 2, 3, 4, 5], vec![16, 17, 18, 19, 6], vec![15, 24, 25, 20, 7], vec![14, 23, 22, 21, 8], vec![13, 12, 11, 10, 9] ] ); } #[test] fn test_n_20() { let result = generate_spiral(20); assert_eq!(result.len(), 20, "Matrix should have 20 rows"); assert_eq!(result[0].len(), 20, "Matrix should have 20 columns"); assert_eq!(result[0][0], 1, "Top-left corner should be 1"); assert_eq!( result[19][19], 400, "Bottom-right corner should be n² (400 for n=20)" ); assert_eq!( result[9][9], 181, "Middle element should match spiral pattern" ); } }
Solution
Click to Show/Hide Solution
#![allow(unused)] fn main() { // Rust Bytes Issue 72: Number Spiral pub fn generate_spiral(n: i32) -> Vec<Vec<i32>> { if n <= 0 { return vec![]; } let mut matrix = vec![vec![0; n as usize]; n as usize]; let (mut row, mut col) = (0, 0); let (mut dr, mut dc) = (0, 1); for i in 1..=(n * n) { matrix[row as usize][col as usize] = i; let next_row = row + dr; let next_col = col + dc; if next_row < 0 || next_row >= n || next_col < 0 || next_col >= n || matrix[next_row as usize][next_col as usize] != 0 { (dr, dc) = (dc, -dr); } row += dr; col += dc; } matrix } #[cfg(test)] mod tests { use super::*; #[test] fn test_n_1() { assert_eq!(generate_spiral(1), vec![vec![1]]); } #[test] fn test_n_2() { assert_eq!(generate_spiral(2), vec![vec![1, 2], vec![4, 3]]); } #[test] fn test_n_3() { assert_eq!( generate_spiral(3), vec![vec![1, 2, 3], vec![8, 9, 4], vec![7, 6, 5]] ); } #[test] fn test_n_0() { assert_eq!(generate_spiral(0), Vec::<Vec<i32>>::new()); } #[test] fn test_n_negative() { assert_eq!(generate_spiral(-1), Vec::<Vec<i32>>::new()); } #[test] fn test_n_4() { assert_eq!( generate_spiral(4), vec![ vec![1, 2, 3, 4], vec![12, 13, 14, 5], vec![11, 16, 15, 6], vec![10, 9, 8, 7] ] ); } #[test] fn test_n_5() { assert_eq!( generate_spiral(5), vec![ vec![1, 2, 3, 4, 5], vec![16, 17, 18, 19, 6], vec![15, 24, 25, 20, 7], vec![14, 23, 22, 21, 8], vec![13, 12, 11, 10, 9] ] ); } #[test] fn test_n_20() { let result = generate_spiral(20); assert_eq!(result.len(), 20, "Matrix should have 20 rows"); assert_eq!(result[0].len(), 20, "Matrix should have 20 columns"); assert_eq!(result[0][0], 1, "Top-left corner should be 1"); assert_eq!( result[19][19], 400, "Bottom-right corner should be n² (400 for n=20)" ); assert_eq!( result[9][9], 181, "Middle element should match spiral pattern" ); } } }