permutation/permutation.rs
1use std;
2use std::cmp::Ordering;
3use std::convert::AsRef;
4
5#[derive(Clone, Debug)]
6pub struct Permutation {
7 forward: bool,
8 indices: Vec<usize>,
9}
10
11impl std::cmp::PartialEq for Permutation {
12 /// This method compares two Permutations for equality, and is used by `==`
13 fn eq(&self, other: &Permutation) -> bool {
14 if self.forward == other.forward {
15 self.indices == other.indices
16 } else {
17 self.indices
18 .iter()
19 .enumerate()
20 .all(|(i, &j)| other.indices[j] == i)
21 }
22 }
23}
24impl std::cmp::Eq for Permutation {}
25impl<'a, 'b> std::ops::Mul<&'b Permutation> for &'a Permutation {
26 type Output = Permutation;
27 /// Multiply permutations, in the mathematical sense.
28 ///
29 /// Given two permutations `a`, and `b`, `a * b` is defined as
30 /// the permutation created by first applying b, then applying a.
31 ///
32 /// # Examples
33 ///
34 /// ```
35 /// # use permutation::Permutation;
36 /// let p1 = Permutation::oneline([1, 0, 2]);
37 /// let p2 = Permutation::oneline([0, 2, 1]);
38 /// assert_eq!(&p1 * &p2, Permutation::oneline([1,2,0]));
39 /// ```
40
41 fn mul(self, rhs: &'b Permutation) -> Self::Output {
42 match (self.forward, rhs.forward) {
43 (_, false) => Permutation::oneline(self.apply_slice(&rhs.indices)).inverse(),
44 (false, true) => return self * &(rhs * &Permutation::one(self.len())),
45 (true, true) => Permutation {
46 forward: true,
47 indices: rhs.apply_inv_slice(&self.indices),
48 },
49 }
50 }
51}
52
53impl Permutation {
54 /// Create a permutation from a vector of indices.
55 ///
56 /// from_vec(v) returns the permutation P such that P applied to [1,2,...,N] is v.
57 /// Note that this notation is the inverse of the usual [one-line notation](https://en.wikipedia.org/wiki/Permutation#Definition_and_notations)
58 /// used in mathematics. This is a known issue and may change in a newer release.
59 ///
60 /// # Examples
61 ///
62 /// ```
63 /// # use permutation::Permutation;
64 /// let vec = vec!['a','b','c','d'];
65 /// let permutation = Permutation::from_vec([0,2,3,1]);
66 /// assert_eq!(permutation.apply_slice(&vec), vec!['a','c','d','b']);
67 /// ```
68 #[deprecated(since = "0.4.0", note = "Please replace with oneline(vec).inverse()")]
69 pub fn from_vec<V>(vec: V) -> Permutation
70 where
71 V: Into<Vec<usize>>,
72 {
73 let result = Permutation {
74 forward: false,
75 indices: vec.into(),
76 };
77
78 debug_assert!(result.valid());
79 return result;
80 }
81
82 /// Create a permutation from zero-based oneline notation
83 ///
84 /// This creates a permutation from [one-line notation](https://en.wikipedia.org/wiki/Permutation#Definition_and_notations)
85 /// notation used in mathematics, but using zero-based indices rather than the one-based indices
86 /// typically used in mathematics.
87 ///
88 /// Note that this is the inverse notation used by the deprecated `Permutation::from_vec()`.
89 ///
90 ///
91 /// # Examples
92 ///
93 /// ```
94 /// # use permutation::Permutation;
95 /// let vec = vec!['a','b','c','d'];
96 /// let permutation = Permutation::oneline([0,2,3,1]);
97 /// assert_eq!(permutation.apply_slice(&vec), vec!['a','d','b','c']);
98 /// ```
99 pub fn oneline<V>(vec: V) -> Permutation
100 where
101 V: Into<Vec<usize>>,
102 {
103 let result = Permutation {
104 forward: true,
105 indices: vec.into(),
106 };
107
108 debug_assert!(result.valid());
109 return result;
110 }
111
112 /// Computes the permutation that would sort a given slice.
113 ///
114 /// This is the same as `permutation::sort()`, but assigned in-place to `self` rather than
115 /// allocating a new permutation.
116 ///
117 /// # Panics
118 ///
119 /// If self.len() != vec.len()
120 ///
121 /// # Examples
122 ///
123 /// ```
124 /// # use permutation::Permutation;
125 /// // Say you have a permutation that we don't need anymore...
126 /// let mut permutation = permutation::sort(&[0,1,2]);
127 ///
128 /// // You can reuse it rather than allocating a new one, as long as the length is the same
129 /// let mut vec = vec!['z','w','h'];
130 /// permutation.assign_from_sort(&vec);
131 /// let permuted = permutation.apply_slice(&vec);
132 /// vec.sort();
133 /// assert_eq!(vec, permuted);
134 ///
135 /// // You can also use it to sort multiple arrays based on the ordering of one.
136 /// let names = vec!["Bob", "Steve", "Jane"];
137 /// let salary = vec![10, 5, 15];
138 /// permutation.assign_from_sort(&salary);
139 /// let ordered_names = permutation.apply_slice(&names);
140 /// let ordered_salaries = permutation.apply_slice(&salary);
141 /// assert_eq!(ordered_names, vec!["Steve", "Bob", "Jane"]);
142 /// assert_eq!(ordered_salaries, vec![5, 10, 15]);
143 /// ```
144 pub fn assign_from_sort<T, S>(&mut self, slice: S)
145 where
146 T: Ord,
147 S: AsRef<[T]>,
148 {
149 let s = slice.as_ref();
150 assert_eq!(self.len(), s.len());
151 //We use the reverse permutation form, because its more efficient for applying to indices.
152 self.indices.sort_by_key(|&i| &s[i]);
153 }
154
155 /// Computes the permutation that would sort a given slice by a comparator.
156 ///
157 /// This is the same as `permutation::sort_by()`, but assigned in-place to `self` rather than
158 /// allocating a new permutation.
159 ///
160 /// # Panics
161 ///
162 /// If self.len() != vec.len()
163 ///
164 /// # Examples
165 ///
166 /// ```
167 /// # use permutation::Permutation;
168 /// // Say you have a permutation that we don't need anymore...
169 /// let mut permutation = permutation::sort(&[0,1,2,3,4,5]);
170 ///
171 /// // You can assign to it rather than allocating a new one, as long as the length is the same
172 /// let mut vec = vec!['z','w','h','a','s','j'];
173 /// permutation.assign_from_sort_by(&vec, |a, b| b.cmp(a));
174 /// let permuted = permutation.apply_slice(&vec);
175 /// vec.sort_by(|a,b| b.cmp(a));
176 /// assert_eq!(vec, permuted);
177 /// ```
178 pub fn assign_from_sort_by<T, S, F>(&mut self, slice: S, mut compare: F)
179 where
180 S: AsRef<[T]>,
181 F: FnMut(&T, &T) -> Ordering,
182 {
183 let s = slice.as_ref();
184 assert_eq!(self.indices.len(), s.len());
185 // We use the reverse permutation form, because its more efficient for applying to indices.
186 self.indices.sort_by(|&i, &j| compare(&s[i], &s[j]));
187 }
188
189 /// Computes the permutation that would sort a given slice by a key function.
190 ///
191 /// This is the same as `permutation::sort_by_key()`, but assigned in-place to `self` rather than
192 /// allocating a new permutation.
193 ///
194 /// # Panics
195 ///
196 /// If self.len() != vec.len()
197 ///
198 /// # Examples
199 ///
200 /// ```
201 /// # use permutation::Permutation;
202 /// // Say you have a permutation that we don't need anymore...
203 /// let mut permutation = permutation::sort(&[0,1,2,3,4,5]);
204 ///
205 /// // You can assign to it rather than allocating a new one, as long as the length is the same
206 /// let mut vec = vec![2, 4, 6, 8, 10, 11];
207 /// permutation.assign_from_sort_by_key(&vec, |a| a % 3);
208 /// let permuted = permutation.apply_slice(&vec);
209 /// vec.sort_by_key(|a| a % 3);
210 /// assert_eq!(vec, permuted);
211 /// ```
212 pub fn assign_from_sort_by_key<T, S, B, F>(&mut self, slice: S, mut f: F)
213 where
214 B: Ord,
215 S: AsRef<[T]>,
216 F: FnMut(&T) -> B,
217 {
218 let s = slice.as_ref();
219 assert_eq!(self.indices.len(), s.len());
220 //We use the reverse permutation form, because its more efficient for applying to indices.
221 self.indices.sort_by_key(|&i| f(&s[i]));
222 }
223 /// Return the identity permutation of size N.
224 ///
225 /// This returns the identity permutation of N elements.
226 ///
227 /// # Examples
228 /// ```
229 /// # use permutation::Permutation;
230 /// let vec = vec!['a','b','c','d'];
231 /// let permutation = Permutation::one(4);
232 /// assert_eq!(permutation.apply_slice(&vec), vec!['a','b','c','d']);
233 /// ```
234 pub fn one(len: usize) -> Permutation {
235 Permutation {
236 forward: false,
237 indices: (0..len).collect(),
238 }
239 }
240 /// Return the size of a permutation.
241 ///
242 /// This is the number of elements that the permutation acts on.
243 ///
244 /// # Examples
245 /// ```
246 /// use permutation::Permutation;
247 /// let permutation = Permutation::one(4);
248 /// assert_eq!(permutation.len(), 4);
249 /// ```
250 pub fn len(&self) -> usize {
251 return self.indices.len();
252 }
253 /// Check whether a permutation is valid.
254 ///
255 /// A permutation can be invalid if it was constructed with an
256 /// incorrect vector using ``::from_vec()`` or ``::oneline()``.
257 /// Debug assertions will catch this on construction, so it should
258 /// never return true.
259 ///
260 pub fn valid(&self) -> bool {
261 let mut sorted = self.indices.clone();
262 sorted.sort();
263 return sorted.iter().enumerate().all(|(i, &j)| i == j);
264 }
265
266 /// Return the inverse of a permutation.
267 ///
268 /// This returns a permutation that will undo a given permutation.
269 /// Internally, this does not compute the inverse, but just flips a bit.
270 ///
271 /// ```
272 /// # use permutation::Permutation;
273 /// let permutation = Permutation::oneline([0,2,3,1]);
274 /// assert_eq!(permutation.inverse(), Permutation::oneline([0,3,1,2]));
275 /// ```
276 pub fn inverse(mut self) -> Permutation {
277 self.forward ^= true;
278 return self;
279 }
280
281 /// Normalize the internal storage of the `Permutation`, optimizing it for forward or inverse application.
282 ///
283 /// Internally, the permutation has a bit to indicate whether it is inverted.
284 /// This is because given a permutation P, it is just as easy to compute `P^-1 * Q`
285 /// as it is to compute `P * Q`. However, computing the entries of `P^-1` requires some computation.
286 /// However, when applying to the permutation to an index, the permutation has a "preferred" direction, which
287 /// is much quicker to compute.
288 ///
289 /// The `normalize()` method does not change the value of the permutation, but
290 /// it converts it into the preferred form for applying `P` or its inverse, respectively.
291 ///
292 /// If `backward` is `false`, it will be in the preferred form for applying `P`,
293 /// if `backward` is `true`, it will be in the preferred form for appling `P^-1`
294 ///
295 /// # Examples
296 ///
297 /// ```
298 /// # use permutation::Permutation;
299 /// let permutation = Permutation::oneline([0, 3, 2, 5, 1, 4]);
300 /// let reversed = permutation.inverse().normalize(true);
301 /// assert_eq!(reversed.apply_inv_idx(3), 5);
302 /// ```
303 pub fn normalize(self, backward: bool) -> Permutation {
304 if self.forward ^ backward {
305 self
306 } else {
307 let len = self.len();
308 if backward {
309 &self * &Permutation::one(len)
310 } else {
311 (&self.inverse() * &Permutation::one(len)).inverse()
312 }
313 }
314 }
315 fn apply_idx_fwd(&self, idx: usize) -> usize {
316 self.indices.iter().position(|&v| v == idx).unwrap()
317 }
318 fn apply_idx_bkwd(&self, idx: usize) -> usize {
319 self.indices[idx]
320 }
321
322 /// Apply the permutation to an index.
323 ///
324 /// Given an index of an element, this will return the new index
325 /// of that element after applying the permutation.
326 ///
327 /// Note that the running time will be O(1) or O(N) depending on
328 /// how the permutation is normalized (see [`Permutation::normalize`]).
329 ///
330 /// # Examples
331 ///
332 /// ```
333 /// # use permutation::Permutation;
334 /// let permutation = Permutation::oneline([0,2,1]);
335 /// assert_eq!(permutation.apply_idx(1), 2);
336 pub fn apply_idx(&self, idx: usize) -> usize {
337 match self.forward {
338 false => self.apply_idx_fwd(idx),
339 true => self.apply_idx_bkwd(idx),
340 }
341 }
342
343 /// Apply the inverse of a permutation to an index.
344 ///
345 /// Given an index of an element, this will return the new index
346 /// of that element after applying 'P^-1'.
347 ///
348 /// Equivalently, if `P.apply_idx(i) == j`, then `P.apply_inv_idx(j) == i`.
349 ///
350 /// Note that the running time will be O(1) or O(N) depending on
351 /// how the permutation is normalized (see [`Permutation::normalize`]).
352 ///
353 /// # Examples
354 ///
355 /// ```
356 /// # use permutation::Permutation;
357 /// let permutation = Permutation::oneline([0,2,1]);
358 /// assert_eq!(permutation.apply_inv_idx(2), 1);
359 /// ```
360 pub fn apply_inv_idx(&self, idx: usize) -> usize {
361 match self.forward {
362 true => self.apply_idx_fwd(idx),
363 false => self.apply_idx_bkwd(idx),
364 }
365 }
366 fn apply_slice_fwd<T: Clone, S>(&self, slice: S) -> Vec<T>
367 where
368 S: AsRef<[T]>,
369 {
370 let s = slice.as_ref();
371 self.indices.iter().map(|&idx| s[idx].clone()).collect()
372 }
373
374 fn apply_slice_bkwd<T: Clone, S>(&self, slice: S) -> Vec<T>
375 where
376 S: AsRef<[T]>,
377 {
378 let s = slice.as_ref();
379 let mut other: Vec<T> = s.to_vec();
380 for (i, idx) in self.indices.iter().enumerate() {
381 other[*idx] = s[i].clone();
382 }
383 return other;
384 }
385
386 // For the in place methods, we apply each cycle in the permutation in turn, marking the indices with their MSB when
387 // they have been resolved. The MSB will always be unset as long as n <= isize::max_value().
388 // This way, we can recover the original indices in O(n) and perform no heap allocations.
389
390 #[inline(always)]
391 fn toggle_mark_idx(idx: usize) -> usize {
392 idx ^ isize::min_value() as usize
393 }
394
395 #[inline(always)]
396 fn idx_is_marked(idx: usize) -> bool {
397 (idx & (isize::min_value() as usize)) != 0
398 }
399
400 fn apply_slice_bkwd_in_place<T, S>(&mut self, slice: &mut S)
401 where
402 S: AsMut<[T]> + ?Sized,
403 {
404 let s = slice.as_mut();
405 assert_eq!(s.len(), self.len());
406 assert!(s.len() <= isize::max_value() as usize);
407
408 for idx in self.indices.iter() {
409 debug_assert!(!Self::idx_is_marked(*idx));
410 }
411
412 for i in 0..self.indices.len() {
413 let i_idx = self.indices[i];
414
415 if Self::idx_is_marked(i_idx) {
416 continue;
417 }
418
419 let mut j = i;
420 let mut j_idx = i_idx;
421
422 // When we loop back to the first index, we stop
423 while j_idx != i {
424 self.indices[j] = Self::toggle_mark_idx(j_idx);
425 s.swap(j, j_idx);
426 j = j_idx;
427 j_idx = self.indices[j];
428 }
429
430 self.indices[j] = Self::toggle_mark_idx(j_idx);
431 }
432
433 for idx in self.indices.iter_mut() {
434 debug_assert!(Self::idx_is_marked(*idx));
435 *idx = Self::toggle_mark_idx(*idx);
436 }
437 }
438
439 fn apply_slice_fwd_in_place<T, S>(&mut self, slice: &mut S)
440 where
441 S: AsMut<[T]> + ?Sized,
442 {
443 let s = slice.as_mut();
444 assert_eq!(s.len(), self.len());
445 assert!(s.len() <= isize::max_value() as usize);
446
447 for idx in self.indices.iter() {
448 debug_assert!(!Self::idx_is_marked(*idx));
449 }
450
451 for i in 0..self.indices.len() {
452 let i_idx = self.indices[i];
453
454 if Self::idx_is_marked(i_idx) {
455 continue;
456 }
457
458 let mut j = i;
459 let mut j_idx = i_idx;
460
461 // When we loop back to the first index, we stop
462 while j_idx != i {
463 self.indices[j] = Self::toggle_mark_idx(j_idx);
464 s.swap(i, j_idx);
465 j = j_idx;
466 j_idx = self.indices[j];
467 }
468
469 self.indices[j] = Self::toggle_mark_idx(j_idx);
470 }
471
472 for idx in self.indices.iter_mut() {
473 debug_assert!(Self::idx_is_marked(*idx));
474 *idx = Self::toggle_mark_idx(*idx);
475 }
476 }
477
478 /// Apply a permutation to a slice of elements
479 ///
480 /// Given a slice of elements, this will permute the elements according
481 /// to this permutation and clone them to a `Vec`.
482 ///
483 /// # Examples
484 ///
485 /// ```
486 /// # use permutation::Permutation;
487 /// let permutation = Permutation::oneline([0,3,1,2]);
488 /// let vec = vec!['a','b','c','d'];
489 /// assert_eq!(permutation.apply_slice(&vec), vec!['a', 'c', 'd', 'b']);
490 /// ```
491 #[must_use]
492 pub fn apply_slice<T: Clone, S>(&self, slice: S) -> Vec<T>
493 where
494 S: AsRef<[T]>,
495 {
496 let s = slice.as_ref();
497 assert_eq!(s.len(), self.len());
498 match self.forward {
499 false => self.apply_slice_fwd(s),
500 true => self.apply_slice_bkwd(s),
501 }
502 }
503 /// Apply the inverse of a permutation to a slice of elements
504 ///
505 /// Given a slice of elements, this will permute the elements according
506 /// to the inverse of this permutation and clone them to a `Vec`.
507 /// This is equivalent to "undoing" the permutation.
508 ///
509 /// # Examples
510 ///
511 /// ```
512 /// # use permutation::Permutation;
513 /// let permutation = Permutation::oneline([0,3,1,2]);
514 /// let vec = vec!['a','b', 'c', 'd'];
515 /// assert_eq!(permutation.apply_inv_slice(vec), vec!['a', 'd', 'b', 'c']);
516 /// ```
517 #[must_use]
518 pub fn apply_inv_slice<T: Clone, S>(&self, slice: S) -> Vec<T>
519 where
520 S: AsRef<[T]>,
521 {
522 let s = slice.as_ref();
523 assert_eq!(s.len(), self.len());
524 match self.forward {
525 false => self.apply_slice_bkwd(s),
526 true => self.apply_slice_fwd(s),
527 }
528 }
529
530 /// Apply a permutation to a slice of elements
531 ///
532 /// Given a slice of elements, this will permute the elements in place according
533 /// to this permutation.
534 ///
535 /// This method borrows `self` mutably to avoid allocations, but the permutation
536 /// will be unchanged after it returns.
537 ///
538 /// # Panics
539 ///
540 /// If `slice.len() != self.len()`.
541 /// If `slice.len()` > isize::max_value(), due to implementation reasons.
542 ///
543 /// # Examples
544 ///
545 /// ```
546 /// # use permutation::Permutation;
547 /// let mut permutation = Permutation::oneline([0,3,1,2]);
548 /// let mut vec = vec!['a', 'b', 'c', 'd'];
549 /// let permutation_old = permutation.clone();
550 /// permutation.apply_slice_in_place(&mut vec);
551 /// assert_eq!(vec, vec!['a', 'c', 'd', 'b']);
552 /// assert_eq!(permutation, permutation_old);
553 /// ```
554 pub fn apply_slice_in_place<T, S>(&mut self, slice: &mut S)
555 where
556 S: AsMut<[T]> + ?Sized,
557 {
558 match self.forward {
559 false => self.apply_slice_bkwd_in_place(slice),
560 true => self.apply_slice_fwd_in_place(slice),
561 }
562 }
563
564 /// Apply the inverse of a permutation to a slice of elements
565 ///
566 /// Given a slice of elements, this will permute the elements in place according
567 /// to the inverse of this permutation.
568 /// This is equivalent to "undoing" the permutation.
569 ///
570 /// This method borrows `self` mutably to avoid allocations, but the permutation
571 /// will be unchanged after it returns.
572 ///
573 /// # Panics
574 ///
575 /// If `slice.len() != self.len()`.
576 /// If `slice.len()` > isize::max_value(), due to implementation reasons.
577 ///
578 /// # Examples
579 ///
580 /// ```
581 /// # use permutation::Permutation;
582 /// let mut permutation = Permutation::oneline([0,3,1,2]);
583 /// let mut vec = vec!['a', 'b', 'c', 'd'];
584 /// permutation.apply_inv_slice_in_place(&mut vec);
585 /// assert_eq!(vec, vec!['a', 'd', 'b', 'c']);
586 /// ```
587 pub fn apply_inv_slice_in_place<T, S>(&mut self, slice: &mut S)
588 where
589 S: AsMut<[T]> + ?Sized,
590 {
591 match self.forward {
592 false => self.apply_slice_fwd_in_place(slice),
593 true => self.apply_slice_bkwd_in_place(slice),
594 }
595 }
596}
597/// Return the permutation that would sort a given slice.
598///
599/// This calculates the permutation that if it were applied to the slice,
600/// would put the elements in sorted order.
601///
602/// # Examples
603///
604/// ```
605/// # use permutation::Permutation;
606/// let mut vec = vec!['z','w','h','a','s','j'];
607/// let permutation = permutation::sort(&vec);
608/// let permuted = permutation.apply_slice(&vec);
609/// vec.sort();
610/// assert_eq!(vec, permuted);
611/// ```
612///
613/// You can also use it to sort multiple arrays based on the ordering of one.
614///
615/// ```
616/// let names = vec!["Bob", "Steve", "Jane"];
617/// let salary = vec![10, 5, 15];
618/// let permutation = permutation::sort(&salary);
619/// let ordered_names = permutation.apply_slice(&names);
620/// let ordered_salaries = permutation.apply_slice(&salary);
621/// assert_eq!(ordered_names, vec!["Steve", "Bob", "Jane"]);
622/// assert_eq!(ordered_salaries, vec![5, 10, 15]);
623/// ```
624pub fn sort<T, S>(slice: S) -> Permutation
625where
626 T: Ord,
627 S: AsRef<[T]>,
628{
629 let s = slice.as_ref();
630 let mut permutation = Permutation::one(s.len());
631 //We use the reverse permutation form, because its more efficient for applying to indices.
632 permutation.indices.sort_by_key(|&i| &s[i]);
633 return permutation;
634}
635
636/// Return the permutation that would sort a given slice, but might not
637/// preserve the order of equal elements.
638///
639/// This calculates the permutation that if it were applied to the slice,
640/// would put the elements in sorted order.
641///
642/// # Examples
643///
644/// ```
645/// # use permutation::Permutation;
646/// let mut vec = vec!['z','w','h','a','s','j'];
647/// let permutation = permutation::sort_unstable(&vec);
648/// let permuted = permutation.apply_slice(&vec);
649/// vec.sort();
650/// assert_eq!(vec, permuted);
651/// ```
652///
653/// You can also use it to sort multiple arrays based on the ordering of one.
654///
655/// ```
656/// let names = vec!["Bob", "Steve", "Jane"];
657/// let salary = vec![10, 5, 15];
658/// let permutation = permutation::sort_unstable(&salary);
659/// let ordered_names = permutation.apply_slice(&names);
660/// let ordered_salaries = permutation.apply_slice(&salary);
661/// assert_eq!(ordered_names, vec!["Steve", "Bob", "Jane"]);
662/// assert_eq!(ordered_salaries, vec![5, 10, 15]);
663/// ```
664pub fn sort_unstable<T, S>(slice: S) -> Permutation
665where
666 T: Ord,
667 S: AsRef<[T]>,
668{
669 let s = slice.as_ref();
670 let mut permutation = Permutation::one(s.len());
671 //We use the reverse permutation form, because its more efficient for applying to indices.
672 permutation.indices.sort_unstable_by_key(|&i| &s[i]);
673 return permutation;
674}
675
676/// Return the permutation that would sort a given slice by a comparator.
677///
678/// This is the same as `permutation::sort()` except that it allows you to specify
679/// the comparator to use when sorting similar to `std::slice.sort_by()`.
680///
681/// If the comparator does not define a total ordering, the order of the elements is unspecified.
682/// Per the [Rust Docs](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.sort_by),
683/// an order is a total order if it is (for all `a`, `b` and `c`):
684///
685/// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
686/// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
687///
688/// # Examples
689///
690/// ```
691/// # use permutation::Permutation;
692/// let mut vec = vec!['z','w','h','a','s','j'];
693/// let permutation = permutation::sort_by(&vec, |a, b| b.cmp(a));
694/// let permuted = permutation.apply_slice(&vec);
695/// vec.sort_by(|a,b| b.cmp(a));
696/// assert_eq!(vec, permuted);
697/// ```
698pub fn sort_by<T, S, F>(slice: S, mut compare: F) -> Permutation
699where
700 S: AsRef<[T]>,
701 F: FnMut(&T, &T) -> Ordering,
702{
703 let s = slice.as_ref();
704 let mut permutation = Permutation::one(s.len());
705 //We use the reverse permutation form, because its more efficient for applying to indices.
706 permutation.indices.sort_by(|&i, &j| compare(&s[i], &s[j]));
707 return permutation;
708}
709
710/// Return the permutation that would sort a given slice by a comparator, but might not
711/// preserve the order of equal elements.
712///
713/// This is the same as `permutation::sort_unstable()` except that it allows you to specify
714/// the comparator to use when sorting similar to `std::slice.sort_unstable_by()`.
715///
716/// If the comparator does not define a total ordering, the order of the elements is unspecified.
717/// Per the [Rust Docs](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.sort_unstable_by),
718/// an order is a total order if it is (for all `a`, `b` and `c`):
719///
720/// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
721/// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
722///
723/// # Examples
724///
725/// ```
726/// # use permutation::Permutation;
727/// let mut vec = vec!['z','w','h','a','s','j'];
728/// let permutation = permutation::sort_unstable_by(&vec, |a, b| b.cmp(a));
729/// let permuted = permutation.apply_slice(&vec);
730/// vec.sort_by(|a,b| b.cmp(a));
731/// assert_eq!(vec, permuted);
732/// ```
733pub fn sort_unstable_by<T, S, F>(slice: S, mut compare: F) -> Permutation
734where
735 S: AsRef<[T]>,
736 F: FnMut(&T, &T) -> Ordering,
737{
738 let s = slice.as_ref();
739 let mut permutation = Permutation::one(s.len());
740 //We use the reverse permutation form, because its more efficient for applying to indices.
741 permutation
742 .indices
743 .sort_unstable_by(|&i, &j| compare(&s[i], &s[j]));
744 return permutation;
745}
746
747/// Return the permutation that would sort a given slice by a key function.
748///
749/// This is the same as `permutation::sort()` except that it allows you to specify
750/// the key function simliar to `std::slice.sort_by_key()`
751///
752/// # Examples
753///
754/// ```
755/// # use permutation::Permutation;
756/// let mut vec = vec![2, 4, 6, 8, 10, 11];
757/// let permutation = permutation::sort_by_key(&vec, |a| a % 3);
758/// let permuted = permutation.apply_slice(&vec);
759/// vec.sort_by_key(|a| a % 3);
760/// assert_eq!(vec, permuted);
761/// ```
762pub fn sort_by_key<T, S, B, F>(slice: S, mut f: F) -> Permutation
763where
764 B: Ord,
765 S: AsRef<[T]>,
766 F: FnMut(&T) -> B,
767{
768 let s = slice.as_ref();
769 let mut permutation = Permutation::one(s.len());
770 //We use the reverse permutation form, because its more efficient for applying to indices.
771 permutation.indices.sort_by_key(|&i| f(&s[i]));
772 return permutation;
773}
774
775/// Return the permutation that would sort a given slice by a key function, but might not
776/// preserve the order of equal elements.
777///
778/// This is the same as `permutation::sort_unstable()` except that it allows you to specify
779/// the key function simliar to `std::slice.sort_unstable_by_key()`
780///
781/// # Examples
782///
783/// ```
784/// # use permutation::Permutation;
785/// let mut vec = vec![2, 4, 6, 8, 10, 11];
786/// let permutation = permutation::sort_unstable_by_key(&vec, |a| a % 3);
787/// let permuted = permutation.apply_slice(&vec);
788/// vec.sort_by_key(|a| a % 3);
789/// assert_eq!(vec, permuted);
790/// ```
791pub fn sort_unstable_by_key<T, S, B, F>(slice: S, mut f: F) -> Permutation
792where
793 B: Ord,
794 S: AsRef<[T]>,
795 F: FnMut(&T) -> B,
796{
797 let s = slice.as_ref();
798 let mut permutation = Permutation::one(s.len());
799 //We use the reverse permutation form, because its more efficient for applying to indices.
800 permutation.indices.sort_unstable_by_key(|&i| f(&s[i]));
801 return permutation;
802}
803
804#[cfg(test)]
805mod tests {
806 use permutation;
807 use permutation::Permutation;
808
809 #[test]
810 fn basics() {
811 let p1 = Permutation::one(5);
812 let p2 = Permutation::one(5);
813 assert!(p1.valid());
814 assert_eq!(p1, p2);
815 let p3 = Permutation::one(6);
816 assert!(p1 != p3);
817
818 assert_eq!(&p1 * &p2, p1);
819 assert_eq!(p1.clone().inverse(), p1);
820 }
821
822 #[test]
823 #[allow(deprecated)]
824 fn from_vec_oneline() {
825 let p_from_vec = Permutation::from_vec(vec![0, 1, 2]);
826 let p_oneline = Permutation::oneline(vec![0, 1, 2]);
827 assert_eq!(p_from_vec, p_oneline);
828 }
829
830 #[test]
831 fn oneline() {
832 let p = Permutation::oneline(vec![0, 1, 2]);
833 assert!(p.valid());
834 }
835 #[test]
836 fn oneline_slice() {
837 let v = vec![0, 1, 2];
838 let p = Permutation::oneline(&v[..]);
839 assert!(p.valid());
840 }
841 #[test]
842 fn oneline_array() {
843 let p = Permutation::oneline([0, 1, 2]);
844 assert!(p.valid());
845 }
846
847 #[test]
848 fn powers() {
849 let id = Permutation::one(3);
850 let p1 = Permutation::oneline([1, 0, 2]);
851 let square = &p1 * &p1;
852 assert_eq!(square, id);
853 let cube = &p1 * □
854 assert_eq!(cube, p1);
855 }
856 #[test]
857 fn prod() {
858 let p1 = Permutation::oneline([1, 0, 2]);
859 let p2 = Permutation::oneline([0, 2, 1]);
860 let prod = &p1 * &p2;
861 assert_eq!(prod, Permutation::oneline([1, 2, 0]));
862 }
863 #[test]
864 fn len() {
865 let p1 = Permutation::oneline([1, 0, 2]);
866 assert_eq!(p1.len(), 3)
867 }
868 fn check_not_equal_inverses(p2: &Permutation, p3: &Permutation) {
869 assert!(*p2 != *p3);
870 assert_eq!(p2 * p3, Permutation::one(p2.len()));
871 assert_eq!(p3 * p2, Permutation::one(p2.len()));
872 assert_eq!(*p2, p3.clone().inverse());
873 assert_eq!(p2.clone().inverse(), *p3);
874 assert!(p2.clone().inverse() != p3.clone().inverse());
875 assert!(p2 * &p3.clone().inverse() != Permutation::one(p2.len()));
876 assert!(&p2.clone().inverse() * p3 != Permutation::one(p2.len()));
877 }
878 #[test]
879 fn inverse() {
880 let p1 = Permutation::oneline([1, 0, 2]);
881 let rev = p1.clone().inverse();
882 assert_eq!(p1, rev);
883
884 //An element and its inverse
885 let p2 = Permutation::oneline([1, 2, 0, 4, 3]);
886 let p3 = Permutation::oneline([2, 0, 1, 4, 3]);
887
888 check_not_equal_inverses(&p2, &p3);
889 println!(
890 "{:?}, {:?}, {:?}",
891 p2.clone().inverse(),
892 p3.clone().inverse(),
893 &p2.clone().inverse() * &p3.clone().inverse()
894 );
895 assert_eq!(
896 &p2.clone().inverse() * &p3.clone().inverse(),
897 Permutation::one(p2.len())
898 );
899
900 //An element, and a distinct element which is not its inverse.
901 let p4 = Permutation::oneline([1, 2, 0, 3, 4]);
902 let p5 = Permutation::oneline([2, 0, 1, 4, 3]);
903
904 assert!(p4 != p5);
905 assert!(p4 != p5.clone().inverse());
906 assert!(p4.clone().inverse() != p5);
907 assert!(p4.clone().inverse() != p5.clone().inverse());
908 assert!(&p4 * &p5 != Permutation::one(p4.len()));
909 assert!(&p5 * &p4 != Permutation::one(p4.len()));
910 assert!(&p4.clone().inverse() * &p5 != Permutation::one(p4.len()));
911 assert!(&p4 * &p5.clone().inverse() != Permutation::one(p4.len()));
912 }
913
914 #[test]
915 fn sort_slice() {
916 let elems = ['a', 'b', 'g', 'e', 'f'];
917 let perm = permutation::sort(&elems[..]);
918 println!("{:?}", perm);
919 assert_eq!(perm, Permutation::oneline([0, 1, 4, 2, 3]));
920 }
921 #[test]
922 fn sort_array() {
923 let elems = ['a', 'b', 'e', 'g', 'f'];
924 permutation::sort(elems);
925 }
926 #[test]
927 fn sort_array_ref() {
928 let elems = ['a', 'b', 'e', 'g', 'f'];
929 permutation::sort(&elems);
930 }
931 #[test]
932 fn sort_vec() {
933 let elems = vec!['a', 'b', 'e', 'g', 'f'];
934 permutation::sort(&elems);
935 }
936 #[test]
937 fn strings() {
938 let elems = ["doggie", "cat", "doggo", "dog", "doggies", "god"];
939 let perm = permutation::sort(&elems);
940 assert_eq!(perm, Permutation::oneline([2, 0, 4, 1, 3, 5]));
941
942 assert!(perm.apply_slice(&elems) == ["cat", "dog", "doggie", "doggies", "doggo", "god"]);
943 let parallel = ["doggie1", "cat1", "doggo1", "dog1", "doggies1", "god1"];
944 let par_permuted = perm.apply_slice(¶llel);
945 println!("{:?}", par_permuted);
946 assert_eq!(
947 par_permuted,
948 ["cat1", "dog1", "doggie1", "doggies1", "doggo1", "god1"]
949 );
950 assert_eq!(perm.apply_inv_slice(par_permuted), parallel);
951 }
952
953 #[test]
954 fn by_key() {
955 let arr = [1, 10, 9, 8];
956 let perm = permutation::sort_by_key(arr, |i| -i);
957 assert_eq!(perm, Permutation::oneline([3, 0, 1, 2]));
958 }
959
960 #[test]
961 fn by_cmp() {
962 let arr = ["aaabaab", "aba", "cas", "aaab"];
963 let perm = permutation::sort_by(arr, |a, b| a.cmp(b));
964 assert_eq!(perm, Permutation::oneline([1, 2, 3, 0]));
965 }
966
967 #[test]
968 fn by_partially_ordered_cmp() {
969 let arr = [1.0, 5.0, 3.0, 2.0, 8.0];
970 let perm = permutation::sort_by(arr, |a, b| a.partial_cmp(b).unwrap());
971 assert!(perm == Permutation::oneline([0, 3, 2, 1, 4]));
972 }
973
974 #[test]
975 fn apply_array() {
976 let arr = [1, 10, 9, 8];
977 let perm = permutation::sort_by_key(arr, |i| -i);
978 assert_eq!(perm, Permutation::oneline([3, 0, 1, 2]));
979 }
980 #[test]
981 fn indices() {
982 let arr = [100, 10, 1, 1000];
983 let perm = permutation::sort_by_key(arr, |x| -x);
984 println!("{:?}", perm.apply_inv_idx(0));
985 assert_eq!(perm.apply_inv_idx(0), 3);
986 assert_eq!(perm.apply_idx(3), 0);
987
988 assert_eq!(perm.apply_inv_idx(1), 0);
989 assert_eq!(perm.apply_idx(0), 1);
990
991 assert_eq!(perm.apply_inv_idx(2), 1);
992 assert_eq!(perm.apply_idx(1), 2);
993
994 assert_eq!(perm.apply_inv_idx(3), 2);
995 assert_eq!(perm.apply_idx(2), 3);
996 }
997 #[test]
998 fn normalize() {
999 let arr = [100, 10, 1, 1000];
1000 let perm = permutation::sort_by_key(arr, |x| -x);
1001 let f = perm.clone().normalize(false);
1002 let b = perm.clone().normalize(true);
1003 assert_eq!(perm, f);
1004 assert_eq!(f, b);
1005 for idx in 0..perm.len() {
1006 assert_eq!(perm.apply_idx(idx), f.apply_idx(idx));
1007 assert_eq!(f.apply_idx(idx), b.apply_idx(idx));
1008 assert_eq!(perm.apply_inv_idx(idx), f.apply_inv_idx(idx));
1009 assert_eq!(f.apply_inv_idx(idx), b.apply_inv_idx(idx));
1010 }
1011 let inv = perm.clone().inverse();
1012 let fi = inv.clone().normalize(false);
1013 let bi = inv.clone().normalize(true);
1014 assert_eq!(inv, fi);
1015 assert_eq!(fi, bi);
1016 for idx in 0..perm.len() {
1017 assert_eq!(inv.apply_idx(idx), fi.apply_idx(idx));
1018 assert_eq!(fi.apply_idx(idx), bi.apply_idx(idx));
1019 assert_eq!(inv.apply_inv_idx(idx), fi.apply_inv_idx(idx));
1020 assert_eq!(fi.apply_inv_idx(idx), bi.apply_inv_idx(idx));
1021 }
1022 }
1023 #[test]
1024 fn normalize_inv() {
1025 let p1 = Permutation::oneline([1, 0, 2]);
1026 let rev = p1.clone().inverse();
1027 assert_eq!(p1, rev);
1028
1029 //An element and its inverse
1030 let mut p2 = Permutation::oneline([2, 0, 1, 4, 3]);
1031 let mut p3 = Permutation::oneline([1, 2, 0, 4, 3]);
1032
1033 p2 = p2.normalize(false);
1034 p3 = p3.normalize(false);
1035 check_not_equal_inverses(&p2, &p3);
1036
1037 p2 = p2.normalize(true);
1038 p3 = p3.normalize(true);
1039 check_not_equal_inverses(&p2, &p3);
1040
1041 p2 = p2.normalize(true);
1042 p3 = p3.normalize(false);
1043 check_not_equal_inverses(&p2, &p3);
1044
1045 p2 = p2.normalize(false);
1046 p3 = p3.normalize(true);
1047 check_not_equal_inverses(&p2, &p3);
1048 }
1049
1050 #[test]
1051 fn apply_slice_in_place_vec() {
1052 let mut p = Permutation::oneline([1, 2, 0, 4, 3]);
1053
1054 let mut vec = vec!['a', 'b', 'c', 'd', 'e'];
1055
1056 p.apply_slice_in_place(&mut vec);
1057 assert_eq!(vec, vec!['c', 'a', 'b', 'e', 'd']);
1058 }
1059
1060 #[test]
1061 fn apply_unnorm_in_place() {
1062 let mut p = Permutation::oneline([1, 2, 0, 4, 3]).normalize(false);
1063 let p_old = p.clone();
1064
1065 let mut vec = ['a', 'b', 'c', 'd', 'e'];
1066
1067 p.apply_slice_in_place(&mut vec);
1068
1069 assert_eq!(vec, ['c', 'a', 'b', 'e', 'd']);
1070 assert_eq!(p.indices, p_old.indices);
1071 assert_eq!(p.forward, p_old.forward);
1072 }
1073
1074 #[test]
1075 fn apply_norm_in_place() {
1076 let mut p = Permutation::oneline([1, 2, 0, 4, 3]).normalize(true);
1077 let p_old = p.clone();
1078
1079 let mut vec = ['a', 'b', 'c', 'd', 'e'];
1080
1081 p.apply_slice_in_place(&mut vec);
1082
1083 assert_eq!(vec, ['c', 'a', 'b', 'e', 'd']);
1084 assert_eq!(p.indices, p_old.indices);
1085 assert_eq!(p.forward, p_old.forward);
1086 }
1087
1088 #[test]
1089 fn apply_inv_unnorm_place() {
1090 let mut p = Permutation::oneline([1, 2, 0, 4, 3])
1091 .inverse()
1092 .normalize(false);
1093 let p_old = p.clone();
1094
1095 let mut vec = ['c', 'a', 'b', 'e', 'd'];
1096
1097 p.apply_slice_in_place(&mut vec);
1098
1099 assert_eq!(vec, ['a', 'b', 'c', 'd', 'e']);
1100 assert_eq!(p.indices, p_old.indices);
1101 assert_eq!(p.forward, p_old.forward);
1102 }
1103
1104 #[test]
1105 fn apply_inv_norm_in_place() {
1106 let mut p = Permutation::oneline([1, 2, 0, 4, 3])
1107 .inverse()
1108 .normalize(true);
1109 let p_old = p.clone();
1110
1111 let mut vec = ['c', 'a', 'b', 'e', 'd'];
1112
1113 p.apply_slice_in_place(&mut vec);
1114
1115 assert_eq!(vec, ['a', 'b', 'c', 'd', 'e']);
1116 assert_eq!(p.indices, p_old.indices);
1117 assert_eq!(p.forward, p_old.forward);
1118 }
1119}