Skip to main content

ps_ecc/polynomial/implementations/
ord.rs

1use std::cmp::Ordering;
2
3use crate::Polynomial;
4
5impl Ord for Polynomial {
6    fn cmp(&self, other: &Self) -> Ordering {
7        self.degree().cmp(&other.degree()).then_with(|| {
8            let d = self.degree() as usize;
9
10            self.coefficients[..=d]
11                .iter()
12                .rev()
13                .cmp(other.coefficients[..=d].iter().rev())
14        })
15    }
16}
17
18#[cfg(test)]
19mod tests {
20    use std::cmp::Ordering::{Equal, Greater, Less};
21
22    use crate::Polynomial;
23
24    #[test]
25    fn equal_zero_polynomials() {
26        let a = Polynomial::default();
27        let b = Polynomial::default();
28
29        assert_eq!(a.cmp(&b), Equal);
30    }
31
32    #[test]
33    fn equal_nonzero_polynomials() {
34        let mut a = Polynomial::default();
35        let mut b = Polynomial::default();
36
37        a.set(2, 5);
38        a.set(0, 3);
39        b.set(2, 5);
40        b.set(0, 3);
41
42        assert_eq!(a.cmp(&b), Equal);
43    }
44
45    #[test]
46    fn higher_degree_is_greater() {
47        let mut a = Polynomial::default();
48        let mut b = Polynomial::default();
49
50        a.set(3, 1);
51        b.set(2, 255);
52
53        assert_eq!(a.cmp(&b), Greater);
54        assert_eq!(b.cmp(&a), Less);
55    }
56
57    #[test]
58    fn same_degree_compare_leading_coefficient() {
59        let mut a = Polynomial::default();
60        let mut b = Polynomial::default();
61
62        a.set(2, 10);
63        b.set(2, 5);
64
65        assert_eq!(a.cmp(&b), Greater);
66        assert_eq!(b.cmp(&a), Less);
67    }
68
69    #[test]
70    fn same_degree_equal_leading_compare_next() {
71        let mut a = Polynomial::default();
72        let mut b = Polynomial::default();
73
74        a.set(2, 5);
75        a.set(1, 10);
76        b.set(2, 5);
77        b.set(1, 3);
78
79        assert_eq!(a.cmp(&b), Greater);
80        assert_eq!(b.cmp(&a), Less);
81    }
82
83    #[test]
84    fn same_degree_differ_only_at_constant() {
85        let mut a = Polynomial::default();
86        let mut b = Polynomial::default();
87
88        a.set(2, 5);
89        a.set(0, 2);
90        b.set(2, 5);
91        b.set(0, 1);
92
93        assert_eq!(a.cmp(&b), Greater);
94        assert_eq!(b.cmp(&a), Less);
95    }
96
97    #[test]
98    fn reflexive() {
99        let mut p = Polynomial::default();
100
101        p.set(3, 7);
102        p.set(1, 2);
103
104        assert_eq!(p.cmp(&p), Equal);
105    }
106
107    #[test]
108    fn transitive() {
109        let mut a = Polynomial::default();
110        let mut b = Polynomial::default();
111        let mut c = Polynomial::default();
112
113        a.set(1, 1);
114        b.set(1, 2);
115        c.set(1, 3);
116
117        assert_eq!(a.cmp(&b), Less);
118        assert_eq!(b.cmp(&c), Less);
119        assert_eq!(a.cmp(&c), Less);
120    }
121}