问题
I have posted my solution in the answers below.
The question will not be updated with even more code to not further increase clutter.
I'm trying to rotate all elements in a Vec<Vec<T>>
clockwise.
The vector is guaranteed to be square, as in v.len() == v[0].len()
.
The idea is to
- find all elements that are equivalent under rotational symmetry to
v
's center - swap these elements in place, using std::mem::swap
My current code does not change the state of the vec. How do I fix this?
fn rotate<T>(v: &mut Vec<Vec<T>>) {
// swap elements equivalent to position i on each ring r
// limit l = side length of current ring
//
// + 0 - - - - + r = 0 -> l = 6
// | + 1 - - + | r = 1 -> l = 4
// | | + 2 + | | r = 2 -> l = 2
// | | | | | |
// | | + - + | | swap:
// | + - - - + | a b c d
// + - - - - - + > b a c d
// > c a b d
// > d a b c
for r in 0..((v.len() + 1) / 2 {
let l = v.len() - 1 - r;
for i in r..l {
let mut a = & pieces[ r ][ r+i ];
let mut b = & pieces[ r+i ][ l-r ];
let mut c = & pieces[ l-r ][l-r-i];
let mut d = & pieces[l-r-i][ r ];
_rot_cw(&mut a, &mut b, &mut c, &mut d)},
}
}
fn _rot_cw<T>(a: &mut T, b: &mut T, c: &mut T, d: &mut T) {
//rotates a->b, b->c, c->d, d->a
std::mem::swap(a, b);
std::mem::swap(a, c);
std::mem::swap(a, d);
}
}
Edit:
Fixed minor issues in the original code above, thanks to @Jmb.
Here's my current code, again running into borrowing issues:
fn rotate_square_slice<T>(slice: &mut Vec<T>, rows: usize) {
for r in 0..(slice.len()+1)/2 {
let l = slice.len() -1 - r;
for i in r..l {
let a = &mut slice.get_mut(rows * r + r+i ).unwrap();
let b = &mut slice.get_mut(rows * (r+i) + l-r ).unwrap();
let c = &mut slice.get_mut(rows * (l-r) + l-r-i).unwrap();
let d = &mut slice.get_mut(rows * (l-r-i) + r ).unwrap();
std::mem::swap(a, b);
std::mem::swap(a, c);
std::mem::swap(a, d);
}
}
}
回答1:
Swapping elements in a slice can be done by using the slice's swap() method.
Solving that problem, the code now looks like this:
fn rotate_square_slice<T>(slice: &mut [T], size: usize) {
for r in 0..(size + 1) / 2 {
let l = size - 1 - r;
for i in r..l {
// b, c & d are the indices with rotational symmetry to a,
// shifted by 90°, 180° & 270° respectively
let a = size * r + r+i ;
let b = size * (r+i) + l-r ;
let c = size * (l-r) + l-r-i;
let d = size * (l-r-i) + r ;
slice.swap(a, b);
slice.swap(a, c);
slice.swap(a, d);
}
}
}
I have, however, run into an issue with correctly indexing the slice. The question can be found here:
Rotational Symmetry Indexing in a 1D "Square" Array
来源:https://stackoverflow.com/questions/60425152/swapping-elements-of-a-slice-in-place