graaf/op/
semidegree_sequence.rs

1//! Iterate a digraph's semidegree sequence.
2//!
3//! # Examples
4//!
5//! ```
6//! use graaf::{
7//!     AddArc,
8//!     AdjacencyList,
9//!     Empty,
10//!     SemidegreeSequence,
11//! };
12//!
13//! let mut digraph = AdjacencyList::empty(3);
14//!
15//! digraph.add_arc(0, 1);
16//! digraph.add_arc(0, 2);
17//! digraph.add_arc(1, 2);
18//! digraph.add_arc(2, 0);
19//!
20//! assert!(digraph.semidegree_sequence().eq([(1, 2), (1, 1), (2, 1)]));
21//! ```
22
23use crate::{
24    Indegree,
25    Outdegree,
26    Vertices,
27};
28
29/// Digraph semidegree sequence
30pub trait SemidegreeSequence {
31    /// Iterate the semidegree sequence of a digraph.
32    ///
33    /// # Examples
34    ///
35    /// ```
36    /// use graaf::{
37    ///     AddArc,
38    ///     AdjacencyList,
39    ///     Empty,
40    ///     SemidegreeSequence,
41    /// };
42    ///
43    /// let mut digraph = AdjacencyList::empty(3);
44    ///
45    /// digraph.add_arc(0, 1);
46    /// digraph.add_arc(0, 2);
47    /// digraph.add_arc(1, 2);
48    /// digraph.add_arc(2, 0);
49    ///
50    /// assert!(digraph.semidegree_sequence().eq([(1, 2), (1, 1), (2, 1)]));
51    /// ```
52    #[must_use]
53    fn semidegree_sequence(&self) -> impl Iterator<Item = (usize, usize)>;
54}
55
56impl<D> SemidegreeSequence for D
57where
58    D: Indegree + Outdegree + Vertices,
59{
60    fn semidegree_sequence(&self) -> impl Iterator<Item = (usize, usize)> {
61        self.vertices()
62            .map(|u| (self.indegree(u), self.outdegree(u)))
63    }
64}
65
66/// `SemidegreeSequence` tests
67#[macro_export]
68macro_rules! test_semidegree_sequence {
69    ($fixture:path) => {
70        use $fixture::{
71            bang_jensen_34,
72            bang_jensen_94,
73            bang_jensen_196,
74            kattis_builddeps,
75            kattis_cantinaofbabel_1,
76            kattis_cantinaofbabel_2,
77            kattis_escapewallmaria_1,
78            kattis_escapewallmaria_2,
79            kattis_escapewallmaria_3,
80        };
81
82        #[test]
83        fn semidegree_sequence_bang_jensen_196() {
84            assert!(bang_jensen_196().semidegree_sequence().eq([
85                (1, 3),
86                (1, 3),
87                (3, 1),
88                (1, 2),
89                (2, 1),
90                (1, 1),
91                (1, 1),
92                (3, 1)
93            ]));
94        }
95
96        #[test]
97        fn semidegree_sequence_bang_jensen_34() {
98            assert!(bang_jensen_34().semidegree_sequence().eq([
99                (1, 1),
100                (1, 1),
101                (0, 3),
102                (1, 0),
103                (2, 0),
104                (1, 1)
105            ]));
106        }
107
108        #[test]
109        fn semidegree_sequence_bang_jensen_94() {
110            assert!(bang_jensen_94().semidegree_sequence().eq([
111                (0, 2),
112                (2, 1),
113                (1, 4),
114                (2, 1),
115                (1, 1),
116                (2, 0),
117                (1, 0)
118            ]));
119        }
120
121        #[test]
122        fn semidegree_sequence_kattis_builddeps() {
123            assert!(kattis_builddeps().semidegree_sequence().eq([
124                (0, 2),
125                (3, 0),
126                (0, 3),
127                (2, 1),
128                (2, 1),
129                (1, 1)
130            ]));
131        }
132
133        #[test]
134        fn semidegree_sequence_kattis_cantinaofbabel_1() {
135            assert!(kattis_cantinaofbabel_1().semidegree_sequence().eq([
136                (1, 1),
137                (2, 3),
138                (2, 1),
139                (2, 6),
140                (2, 1),
141                (2, 1),
142                (2, 2),
143                (3, 1),
144                (0, 2),
145                (1, 2),
146                (3, 1),
147                (2, 1)
148            ]));
149        }
150
151        #[test]
152        fn semidegree_sequence_kattis_cantinaofbabel_2() {
153            assert!(kattis_cantinaofbabel_2().semidegree_sequence().eq([
154                (2, 1),
155                (1, 2),
156                (1, 3),
157                (2, 1),
158                (1, 1),
159                (2, 2),
160                (1, 1),
161                (3, 1),
162                (1, 3),
163                (2, 1),
164                (1, 2),
165                (2, 1)
166            ]));
167        }
168
169        #[test]
170        fn semidegree_sequence_kattis_escapewallmaria_1() {
171            assert!(kattis_escapewallmaria_1().semidegree_sequence().eq([
172                (0, 0),
173                (0, 0),
174                (0, 0),
175                (0, 0),
176                (0, 0),
177                (2, 2),
178                (1, 1),
179                (0, 0),
180                (0, 0),
181                (2, 2),
182                (0, 0),
183                (0, 0),
184                (1, 0),
185                (1, 2),
186                (0, 0),
187                (0, 0)
188            ]));
189        }
190
191        #[test]
192        fn semidegree_sequence_kattis_escapewallmaria_2() {
193            assert!(kattis_escapewallmaria_2().semidegree_sequence().eq([
194                (0, 0),
195                (0, 0),
196                (0, 0),
197                (0, 0),
198                (0, 0),
199                (2, 2),
200                (1, 1),
201                (0, 0),
202                (0, 0),
203                (2, 1),
204                (0, 0),
205                (0, 0),
206                (1, 1),
207                (1, 2),
208                (0, 0),
209                (0, 0)
210            ]));
211        }
212
213        #[test]
214        fn semidegree_sequence_kattis_escapewallmaria_3() {
215            assert!(kattis_escapewallmaria_3().semidegree_sequence().eq([
216                (0, 0),
217                (2, 2),
218                (2, 2),
219                (0, 0),
220                (0, 0),
221                (3, 3),
222                (2, 2),
223                (0, 0),
224                (0, 0),
225                (2, 2),
226                (0, 0),
227                (0, 0),
228                (1, 1),
229                (2, 2),
230                (0, 0),
231                (0, 0)
232            ]));
233        }
234    };
235}