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 * &square;
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(&parallel);
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}