permutation_rs/group/
calculation.rs1use std::collections::VecDeque;
4use super::GroupElement;
5use super::permutation::Permutation;
6
7pub fn elements_generated_by(generators: &Vec<Permutation>) -> Vec<Permutation> {
12 let mut elements: Vec<Permutation> = vec!();
13 let mut to_visit: VecDeque<Permutation> = VecDeque::new();
14 to_visit.push_back(identity(generators));
15
16 while !to_visit.is_empty() {
17 let element = to_visit.pop_front().unwrap();
18 elements.push(element.clone());
19
20 for ref g in generators {
21 let next = element.times(g);
22 if !elements.contains(&next) && !to_visit.contains(&next) {
23 to_visit.push_back(next);
24 }
25 }
26 }
27
28 elements
29}
30
31pub fn identity<G>(generators: &Vec<G>) -> G where G: GroupElement {
34 let g = generators.get(0).expect("at least one generator");
35 let inverse = g.inverse();
36 g.times(&inverse)
37}
38
39
40pub fn fact(m: u64) -> u64 {
44 (1..m)
45 .map(|n| n + 1)
46 .fold(1u64, |acc, n| acc * n)
47}
48
49#[cfg(test)]
50mod tests {
51 use std::collections::HashMap;
52 use super::super::GroupElement;
53 use super::super::permutation::Permutation;
54 use super::*;
55
56 #[test]
57 fn elements_generated_by_should_calculate_group_elements() {
58 let mut rotation_images = HashMap::new();
59 rotation_images.insert(0u64, 1u64);
60 rotation_images.insert(1u64, 2u64);
61 rotation_images.insert(2u64, 0u64);
62 let rotation = Permutation::new(rotation_images);
63 let id = rotation.times(&rotation.inverse());
64
65 let elements = elements_generated_by(&vec!(rotation.clone()));
66
67 assert!(elements.contains(&id));
68 assert!(elements.contains(&rotation));
69 assert!(elements.contains(&rotation.inverse()));
70 }
71
72 #[test]
73 fn factorial() {
74 assert_eq!(fact(1), 1);
75 assert_eq!(fact(2), 2);
76 assert_eq!(fact(3), 6);
77 assert_eq!(fact(4), 24);
78 }
79}