1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#![feature(test)] extern crate test; #[cfg(test)] mod tests { use super::snail_rect; use test::Bencher; #[bench] fn bench_7kx7k(b: &mut Bencher) { b.iter( || snail_rect(7000, 7000) ); } #[bench] fn bench_20kx20k(b: &mut Bencher) { b.iter( || snail_rect(20000, 20000) ); } #[test] fn width_0_with_height_0() { let actual = snail_rect(0, 0); let excepted = vec![]; assert_eq!(actual, excepted); } #[test] fn width_3_with_height_4() { let actual = snail_rect(3, 4); let excepted = vec![(0,0), (0,1), (0,2), (1,2), (2,2), (3,2), (3,1), (3,0), (2,0), (1,0), (1,1), (2,1)]; assert_eq!(actual, excepted); } } pub fn snail_rect(width: usize, height: usize) -> Vec<(u32, u32)> { fn is_odd(num: usize) -> usize { 2 - (num & 1) } let mut re = Vec::with_capacity(width * height); for ((width, height), off) in (is_odd(width)..=width).rev().step_by(2) .zip((is_odd(height)..=height).rev().step_by(2)) .zip(0u32..) { if width == 1 { re.extend((0..height).map(|i| (off + i as u32 , off) ) ); break; } if height == 1 { re.extend((0..width).map(|i| (off, off + i as u32) )); break; } re.extend((0..width - 1).map(|i| (off, i as u32 + off) )); re.extend((0..height - 1).map(|i| (off + i as u32, off + width as u32 - 1) )); re.extend((1..width).rev().map(|i| (off + height as u32 - 1, off + i as u32) )); re.extend((1..height).rev().map(|i| (i as u32 + off, off ) )); } re }