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

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

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

            
20
1468
    true
21
1668
}
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
}