I managed to find a way to rotate a slice in-place (previous question on SO). The slice is linear, but represents a 2d square of elements.
Is this approach efficient?
Please check the previous question linked above if anything is unclear about the algorithm.
Code
enum Rotation {
Clockwise,
Counterclockwise,
}
fn rotate_square_slice<T>(slice: &mut [T], s: usize, rotation: Rotation) {
// iterate ringwise, from outer to inner
// skip center when size % 2 == 1
for r in 0..s / 2 {
// for all unique indices under rotational symmetry ...
for i in 0..s - (2 * r) - 1{
// ... get their 4 corresponding positions ...
let a = s * ( r ) + r+i ;
let b = s * ( r+i ) + s-r-1 ;
let c = s * ( s-r-1 ) + s-r-i-1 ;
let d = s * (s-r-i-1) + r ;
//... and swap them in the correct direction.
match rotation {
Rotation::Clockwise => {
slice.swap(a, b);
slice.swap(a, c);
slice.swap(a, d);
},
Rotation::Counterclockwise => {
slice.swap(a, b);
slice.swap(c, d);
slice.swap(b, d);
}
}
}
}
}