1use serde::{Deserialize, Serialize};
2use std::cell::RefCell;
3use std::cmp::max;
4use std::rc::Rc;
5
6#[derive(Clone, Debug, Deserialize, Serialize)]
12pub struct Permutation {
13 values: Rc<Vec<usize>>,
14 inv_values: RefCell<Option<Rc<Vec<usize>>>>,
15}
16
17impl Permutation {
18 pub fn id() -> Self {
20 Self {
21 values: Rc::new(Vec::new()),
22 inv_values: RefCell::new(Some(Rc::new(Vec::new()))),
23 }
24 }
25
26 pub fn is_id(&self) -> bool {
34 self.values.is_empty()
35 }
36
37 pub fn as_vec(&self) -> &[usize] {
39 &self.values[..]
40 }
41
42 fn make_inverse(values: Rc<Vec<usize>>, inv_values: Rc<Vec<usize>>) -> Self {
44 Self {
45 values: inv_values,
46 inv_values: RefCell::new(Some(values)),
47 }
48 }
49
50 pub fn apply(&self, x: usize) -> usize {
56 if x < self.values.len() {
57 self.values[x]
58 } else {
59 x
60 }
61 }
62
63 pub fn from_vec(mut values: Vec<usize>) -> Self {
72 while !values.is_empty() && values[values.len() - 1] == values.len() - 1 {
73 values.pop();
74 }
75 if cfg!(debug_assertions) {
77 let mut val_cpy = values.clone();
78 val_cpy.sort();
79 for i in val_cpy.into_iter().enumerate() {
80 assert_eq!(i.0, i.1)
81 }
82 }
83 Self {
84 values: Rc::new(values),
85 inv_values: RefCell::new(None),
86 }
87 }
88
89 pub fn inv(&self) -> Self {
98 if self.inv_values.borrow().is_some() {
99 return Self::make_inverse(self.values.clone(), self.inv_values.borrow().clone().unwrap());
100 }
101
102 let mut v = vec![0; self.values.len()];
103 for i in 0..self.values.len() {
104 v[self.values[i]] = i;
105 }
106
107 let ptr = Rc::new(v);
108
109 *self.inv_values.borrow_mut() = Some(ptr.clone());
110
111 Self::make_inverse(self.values.clone(), ptr)
112 }
113
114 pub fn multiply(&self, other: &Self) -> Self {
122 if self.is_id() {
123 if other.is_id() {
124 return self.clone();
125 }
126 let size = other.lmp().unwrap();
127 Self::from_vec((0..=size).map(|x| other.apply(x)).collect())
128 } else if other.is_id() {
129 self.clone()
130 } else {
131 let size = max(self.lmp().unwrap_or(0), other.lmp().unwrap_or(0));
132 debug_assert!(size > 0);
133 let v = (0..=size).map(|x| self.apply(other.apply(x))).collect();
134 Self::from_vec(v)
135 }
136 }
137
138 pub fn lmp(&self) -> Option<usize> {
139 if self.values.is_empty() {
140 None
141 } else {
142 Some(self.values.len() - 1)
143 }
144 }
145}
146
147impl PartialEq for Permutation {
148 fn eq(&self, other: &Self) -> bool {
149 self.values == other.values
150 }
151}
152
153impl Eq for Permutation {}
154
155impl PartialOrd for Permutation {
156 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
157 Some(self.cmp(other))
158 }
159}
160
161impl Ord for Permutation {
162 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
163 self.values.cmp(&other.values)
164 }
165}
166
167impl std::hash::Hash for Permutation {
168 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
169 self.values.hash(state);
170 }
171}
172
173impl From<Vec<usize>> for Permutation {
174 fn from(v: Vec<usize>) -> Self {
175 Self::from_vec(v)
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::Permutation;
182 #[test]
183 fn id_perm() {
184 assert_eq!(Permutation::id(), Permutation::id());
185 assert_eq!(Permutation::id(), Permutation::from_vec(vec![0, 1, 2]));
186 }
187
188 #[test]
189 fn test_is_id() {
190 let perm = Permutation::from_vec(vec![0, 1, 2]);
191 assert!(perm.is_id());
192 let perm = Permutation::from_vec(vec![0, 2, 1, 4, 3]);
193 assert!(perm.multiply(&perm.inv()).is_id())
194 }
195
196 #[test]
197 fn leq_perm() {
198 assert!(Permutation::id() <= Permutation::id());
199 assert!(!(Permutation::id() < Permutation::id()));
200 assert!(Permutation::id() <= Permutation::from_vec(vec![0, 1, 2]));
201 assert!(!(Permutation::id() < Permutation::from_vec(vec![0, 1, 2])));
202
203 let id = Permutation::id();
204 let cycle = Permutation::from_vec(vec![1, 2, 0]);
205 assert!(id < cycle);
206 assert!(!(id > cycle));
207 }
208
209 #[test]
210 fn not_eq_perm() {
211 assert_ne!(Permutation::id(), Permutation::from_vec(vec![2, 1, 0]));
212 }
213
214 #[test]
215 fn apply_perm() {
216 let id = Permutation::id();
217 let cycle = Permutation::from_vec(vec![1, 2, 0]);
218
219 assert_eq!(0, id.apply(0));
220 assert_eq!(1, id.apply(1));
221 assert_eq!(1, cycle.apply(0));
222 assert_eq!(2, cycle.apply(1));
223 assert_eq!(0, cycle.apply(2));
224 assert_eq!(3, cycle.apply(3));
225 }
226
227 #[test]
228 fn mult_perm() {
229 let id = Permutation::id();
230 let cycle = Permutation::from_vec(vec![1, 2, 0]);
231 let cycle2 = Permutation::from_vec(vec![2, 0, 1]);
232
233 let id = &id;
234 let cycle = &cycle;
235 let cycle2 = &cycle2;
236
237 assert_eq!(*id, id.multiply(id));
238 assert_eq!(*cycle, cycle.multiply(id));
239 assert_eq!(*cycle, id.multiply(cycle));
240 assert_eq!(*cycle2, cycle.multiply(cycle));
241 assert_eq!(*id, cycle.multiply(cycle).multiply(cycle));
242 assert_ne!(*cycle, cycle.multiply(cycle));
243 }
244}