1use super::Mutation;
2use crate::chromosone::Gene;
3
4#[cfg(test)]
5use mockall::*;
6
7#[mockall_double::double]
8use crate::rando::Rando;
9pub struct Rotate<const N: usize, const NSYMS: usize> {
13 pub n: usize,
14}
15
16impl<const N: usize, const NSYMS: usize> Rotate<N, NSYMS> {
17 pub const fn new(n: usize) -> Rotate<N, NSYMS> {
18 Rotate { n }
19 }
20}
21
22impl<const N: usize, const NSYMS: usize> Mutation<N, NSYMS> for Rotate<N, NSYMS> {
23 fn run(&self, chromosone: &[Gene; N], rng: &mut Rando) -> [Gene; N] {
24 let mut mutated = chromosone.clone();
25 let mut curpos = rng.gen_range(0..chromosone.len());
26 let origval = chromosone[curpos];
27 let mut nextpos = curpos;
28 for _ in 0..self.n {
29 nextpos = rng.gen_range(0..chromosone.len());
30 mutated[curpos] = chromosone[nextpos];
31 curpos = nextpos;
32 }
33 mutated[nextpos] = origval;
34 mutated
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn test_rotate1() {
44 let mut r = Rando::default();
45 let m = Rotate::<5, 3>::new(1);
46 r.expect_gen_range()
47 .with(predicate::eq(0..5))
48 .times(1)
49 .return_const(1usize);
50 r.expect_gen_range()
51 .with(predicate::eq(0..5))
52 .times(1)
53 .return_const(3usize);
54 assert_eq!(m.run(&[0, 1, 2, 0, 1], &mut r), [0, 0, 2, 1, 1]);
55 }
56
57 #[test]
58 fn test_rotate2() {
59 let mut r = Rando::default();
60 let m = Rotate::<5, 3>::new(2);
61 r.expect_gen_range()
62 .with(predicate::eq(0..5))
63 .times(1)
64 .return_const(0usize);
65 r.expect_gen_range()
66 .with(predicate::eq(0..5))
67 .times(1)
68 .return_const(1usize);
69 r.expect_gen_range()
70 .with(predicate::eq(0..5))
71 .times(1)
72 .return_const(2usize);
73 assert_eq!(m.run(&[0, 1, 2, 0, 1], &mut r), [1, 2, 0, 0, 1]);
74 }
75}