Skip to main content

fp_collections/
set.rs

1// Reference Implementation: https://github.com/lucasaiu/ocaml/blob/master/stdlib/set.ml
2#![macro_use]
3use std::cmp::max;
4use std::cmp::Ordering;
5use std::fmt::Debug;
6
7#[derive(PartialEq, Eq, Clone, Debug)]
8pub enum Set<T> {
9    Node(Box<Set<T>>, T, Box<Set<T>>, i64),
10    Empty,
11}
12
13#[macro_export]
14macro_rules! set[
15    [$($x:expr),*] => {{
16        let mut s = Set::new();
17        $( s = s.add($x); )*
18        s
19    }};
20];
21
22impl<T: Eq> Set<T> {
23    pub fn new() -> Self {
24        Set::Empty
25    }
26
27    pub fn is_empty(&self) -> bool {
28        self.eq(&Set::Empty)
29    }
30
31    pub fn len(&self) -> u32 {
32        fn aux<T>(xs: &Set<T>, size: u32) -> u32 {
33            match *xs {
34                Set::Empty => 0,
35                Set::Node(ref left, _, ref right, _) => aux(left, 1 + aux(right, size)),
36            }
37        };
38
39        aux(self, 0)
40    }
41}
42
43impl<T: Clone> Set<T>
44where
45    T: Ord,
46{
47    #[allow(clippy::should_implement_trait, clippy::many_single_char_names)]
48    pub fn add(self, x: T) -> Self {
49        match self.clone() {
50            Set::Empty => Set::create_node(x),
51            Set::Node(left, val, right, h) => match x.cmp(&val) {
52                Ordering::Equal => self,
53                Ordering::Less => {
54                    let root = Set::Node(Box::new(left.add(x)), val, right, h);
55                    match root {
56                        Set::Node(l, v, r, _) => Set::balance(
57                            Set::Node(
58                                l.clone(),
59                                v,
60                                r.clone(),
61                                1 + max(Set::height(&l), Set::height(&r)),
62                            ),
63                            *l,
64                        ),
65                        Set::Empty => Set::Empty,
66                    }
67                }
68                Ordering::Greater => {
69                    let root = Set::Node(left, val, Box::new(right.add(x)), h);
70                    match root {
71                        Set::Node(l, v, r, _) => Set::balance(
72                            Set::Node(
73                                l.clone(),
74                                v,
75                                r.clone(),
76                                1 + max(Set::height(&l), Set::height(&r)),
77                            ),
78                            *r,
79                        ),
80                        Set::Empty => Set::Empty,
81                    }
82                }
83            },
84        }
85    }
86
87    fn height(s: &Set<T>) -> i64 {
88        match *s {
89            Set::Node(_, _, _, h) => h,
90            Set::Empty => -1,
91        }
92    }
93
94    fn right_rotate(parent: Set<T>, node: Set<T>) -> Self {
95        match (parent, node) {
96            (
97                Set::Node(_, parent_val, parent_right, _),
98                Set::Node(node_left, node_val, node_right, _),
99            ) => {
100                let h1 = 1 + max(Set::height(&parent_right), Set::height(&node_right));
101                let h2 = 1 + max(h1, Set::height(&node_left));
102                Set::Node(
103                    node_left,
104                    node_val,
105                    Box::new(Set::Node(node_right, parent_val, parent_right, h1)),
106                    h2,
107                )
108            }
109            (_, _) => Set::Empty,
110        }
111    }
112
113    fn left_rotate(parent: Set<T>, node: Set<T>) -> Self {
114        match (parent, node) {
115            (
116                Set::Node(parent_left, parent_val, _, _),
117                Set::Node(node_left, node_val, node_right, _),
118            ) => {
119                let h1 = 1 + max(Set::height(&parent_left), Set::height(&node_left));
120                let h2 = 1 + max(h1, Set::height(&node_right));
121                Set::Node(
122                    Box::new(Set::Node(parent_left, parent_val, node_left, h1)),
123                    node_val,
124                    node_right,
125                    h2,
126                )
127            }
128            (_, _) => Set::Empty,
129        }
130    }
131
132    fn balance(parent: Set<T>, node: Set<T>) -> Self {
133        match parent.clone() {
134            Set::Empty => parent,
135            Set::Node(parent_left, _, parent_right, _) => match node {
136                Set::Empty => parent,
137                Set::Node(ref node_left, _, ref node_right, _) => {
138                    let diff = Set::height(&parent_left) - Set::height(&parent_right);
139                    if diff.abs() > 1 {
140                        if diff > 0 {
141                            let node_diff = Set::height(node_left) - Set::height(node_right);
142                            if node_diff > 0 {
143                                return Set::right_rotate(parent, node);
144                            } else {
145                                return Set::right_rotate(
146                                    parent,
147                                    Set::left_rotate(node.clone(), *node_right.clone()),
148                                );
149                            }
150                        } else {
151                            let node_diff = Set::height(node_left) - Set::height(node_right);
152                            if node_diff < 0 {
153                                return Set::left_rotate(parent, node);
154                            } else {
155                                return Set::left_rotate(
156                                    parent,
157                                    Set::right_rotate(node.clone(), *node_left.clone()),
158                                );
159                            }
160                        }
161                    }
162                    parent
163                }
164            },
165        }
166    }
167
168    fn create_node(x: T) -> Self {
169        Set::Node(Box::new(Set::Empty), x, Box::new(Set::Empty), 0)
170    }
171
172    // TODO: fix later
173    #[allow(clippy::wrong_self_convention)]
174    pub fn to_vec(self) -> Vec<T> {
175        let mut v = vec![];
176        fn aux<I>(n: Set<I>, vs: &mut Vec<I>) -> &mut Vec<I> {
177            match n {
178                Set::Empty => vs,
179                Set::Node(l, v, r, _) => {
180                    aux(*l, vs);
181                    vs.push(v);
182                    aux(*r, vs);
183                    vs
184                }
185            }
186        }
187
188        aux(self, &mut v);
189
190        v
191    }
192
193    pub fn mem(self, x: T) -> bool {
194        match self {
195            Set::Empty => false,
196            Set::Node(l, v, r, _) => match x.cmp(&v) {
197                Ordering::Equal => true,
198                Ordering::Less => l.mem(x),
199                Ordering::Greater => r.mem(x),
200            },
201        }
202    }
203
204    pub fn remove(self, x: T) -> Self {
205        match self {
206            Set::Empty => Set::Empty,
207            Set::Node(left, val, right, h) => match x.cmp(&val) {
208                Ordering::Equal => match (*left.clone(), *right.clone()) {
209                    (Set::Empty, Set::Empty) => Set::Empty,
210                    (Set::Node(_, _, _, _), Set::Empty) => *left,
211                    (Set::Empty, Set::Node(_, _, _, _)) => *right,
212                    (Set::Node(_, _, _, _), Set::Node(_, _, _, _)) => {
213                        let max = left.max_elt();
214                        let root = Set::Node(Box::new(left.remove(max.clone())), max, right, h);
215                        match root.clone() {
216                            Set::Empty => Set::Empty,
217                            Set::Node(l, _, _, _) => Set::balance(root, *l),
218                        }
219                    }
220                },
221                Ordering::Less => {
222                    let root = Set::Node(Box::new(left.clone().remove(x)), val, right, h);
223                    match root.clone() {
224                        Set::Node(l, _, _, _) => Set::balance(root, *l),
225                        Set::Empty => Set::Empty,
226                    }
227                }
228                Ordering::Greater => {
229                    let root = Set::Node(left, val, Box::new(right.clone().remove(x)), h);
230                    match root.clone() {
231                        Set::Node(_, _, r, _) => Set::balance(root, *r),
232                        Set::Empty => Set::Empty,
233                    }
234                }
235            },
236        }
237    }
238
239    pub fn max_elt(&self) -> T {
240        match self {
241            Set::Empty => panic!("Not Found"),
242            Set::Node(_, v, right, _) => match (**right).clone() {
243                Set::Empty => v.clone(),
244                Set::Node(_, _, _, _) => right.max_elt(),
245            },
246        }
247    }
248}
249
250impl<T> From<Vec<T>> for Set<T>
251where
252    T: Eq + Clone + Ord,
253{
254    fn from(xs: Vec<T>) -> Self {
255        xs.iter().fold(Set::new(), |s, x| s.add(x.clone()))
256    }
257}
258
259impl<T> Default for Set<T> {
260    fn default() -> Self {
261        Set::Empty
262    }
263}