1
/// Returns true iff the given permutation is a bijective mapping within the 0..max range.
2
1350
pub fn is_valid_permutation<P>(permutation: P, max: usize) -> bool
3
1350
where
4
1350
    P: Fn(usize) -> usize,
5
{
6
1350
    let mut visited = vec![false; max];
7

            
8
19722
    for i in 0..max {
9
        // Out of bounds
10
19722
        if permutation(i) >= max {
11
100
            return false;
12
19622
        }
13

            
14
19622
        if visited[permutation(i)] {
15
100
            return false;
16
19522
        }
17
19522
        visited[permutation(i)] = true;
18
    }
19

            
20
1150
    true
21
1350
}
22

            
23
#[cfg(test)]
24
mod tests {
25

            
26
    use super::*;
27

            
28
    use crate::random_test;
29
    use rand::seq::SliceRandom;
30

            
31
    #[test]
32
1
    fn test_random_is_valid_permutation() {
33
100
        random_test(100, |rng| {
34
            // Generate a valid permutation.
35
100
            let valid_permutation: Vec<usize> = {
36
100
                let mut order: Vec<usize> = (0..100).collect();
37
100
                order.shuffle(rng);
38
100
                order
39
            };
40

            
41
30000
            assert!(is_valid_permutation(|i| valid_permutation[i], valid_permutation.len()));
42

            
43
            // Generate an invalid permutation (duplicate entries).
44
100
            let invalid_permutation = [0, 1, 2, 3, 4, 5, 6, 7, 8, 8];
45
100
            assert!(!is_valid_permutation(
46
2900
                |i| invalid_permutation[i],
47
100
                invalid_permutation.len()
48
            ));
49

            
50
            // Generate an invalid permutation (missing entries).
51
100
            let invalid_permutation = [0, 1, 3, 4, 5, 6, 7, 8];
52
100
            assert!(!is_valid_permutation(
53
2200
                |i| invalid_permutation[i],
54
100
                invalid_permutation.len()
55
            ));
56
100
        });
57
1
    }
58
}