1use std::{fmt::Debug, hash::Hash};
2
3use crate::Graph;
4
5pub fn all_cycles<T: Eq + Hash + Clone + Debug>(
6 mut graph: Graph<T>,
7) -> Vec<Vec<T>> {
8 let mut result = Vec::new();
9
10 for key in graph.keys() {
11 for paths in graph.remove(&key) {
12 for path in paths {
13 if &path.target != &key {
14 continue;
15 }
16
17 result.push(Vec::from(path))
18 }
19 }
20 }
21
22 result
23}
24
25#[cfg(test)]
26mod tests {
27 use std::collections::HashSet;
28
29 use crate::Cycle;
30
31 use super::*;
32 use pretty_assertions::assert_eq;
33
34 fn to_set(cycles: Vec<Vec<u32>>) -> HashSet<Cycle<u32>> {
35 cycles
36 .into_iter()
37 .map(|c| Cycle::new(c))
38 .collect::<HashSet<_>>()
39 }
40
41 #[test]
42 fn p3() {
43 let graph = Graph::from_edges(vec![(0, 1)]).unwrap();
44
45 assert_eq!(all_cycles(graph), Vec::<Vec<u32>>::new())
46 }
47
48 #[test]
49 fn c3() {
50 let graph = Graph::from_edges(vec![(0, 1), (1, 2), (2, 0)]).unwrap();
51
52 assert_eq!(
53 to_set(all_cycles(graph)),
54 HashSet::from([Cycle::new(vec![0, 1, 2])])
55 )
56 }
57
58 #[test]
59 fn butterfly() {
60 let graph = Graph::from_edges(vec![
61 (0, 1),
62 (1, 2),
63 (2, 3),
64 (3, 4),
65 (4, 2),
66 (2, 0),
67 ])
68 .unwrap();
69
70 assert_eq!(
71 to_set(all_cycles(graph)),
72 HashSet::from([
73 Cycle::new(vec![0, 1, 2]),
74 Cycle::new(vec![2, 3, 4])
75 ])
76 )
77 }
78
79 #[test]
80 fn diamond() {
81 let graph =
82 Graph::from_edges(vec![(0, 1), (1, 2), (2, 0), (2, 3), (3, 1)])
83 .unwrap();
84
85 assert_eq!(
86 to_set(all_cycles(graph)),
87 HashSet::from([
88 Cycle::new(vec![0, 1, 2]),
89 Cycle::new(vec![1, 2, 3]),
90 Cycle::new(vec![0, 1, 3, 2])
91 ])
92 )
93 }
94
95 #[test]
96 fn k4() {
97 let graph = Graph::from_edges(vec![
98 (0, 1),
99 (1, 2),
100 (2, 3),
101 (3, 0),
102 (0, 2),
103 (1, 3)
104 ])
105 .unwrap();
106
107 assert_eq!(
108 to_set(all_cycles(graph)),
109 HashSet::from([
110 Cycle::new(vec![0, 1, 2]),
111 Cycle::new(vec![0, 1, 3]),
112 Cycle::new(vec![0, 2, 3]),
113 Cycle::new(vec![1, 2, 3]),
114 Cycle::new(vec![1, 2, 0, 3]),
115 Cycle::new(vec![1, 0, 2, 3]),
116 Cycle::new(vec![0, 1, 2, 3])
117 ])
118 )
119 }
120
121 #[test]
123 fn k5() {
124 let graph = Graph::from_edges(vec![
125 (0, 1),
126 (1, 2),
127 (2, 3),
128 (3, 4),
129 (4, 0),
130 (0, 3),
131 (0, 2),
132 (1, 3),
133 (1, 4),
134 (2, 4),
135 ]).unwrap();
136
137 assert_eq!(all_cycles(graph).len(), 37 * 2)
138 }
139}