number_encoding/
factoradics.rs

1// Copyright 2019-2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Factorial number system
16//!
17//! See [wikipedia] for more information.
18//!
19//! [wikipedia]: https://en.wikipedia.org/wiki/Factorial_number_system
20
21#[cfg(feature = "alloc")]
22use alloc::vec::Vec;
23
24/// Applies the permutation of the value `p` to the slice `xs`.
25///
26/// The applied permutation can be encoded with [`encode`] to get back `p`.
27///
28/// ```rust
29/// # use number_encoding::factoradics::{decode_mut, encode};
30/// # let mut xs = [0, 1, 2, 3];
31/// # let p = 15;
32/// decode_mut(&mut xs, p);
33/// assert_eq!(encode(&xs), p);
34/// ```
35///
36/// See [`decode`] for a version that allocates a vector for the permutation.
37///
38/// # Panics
39///
40/// Panics in debug mode if `xs` is not increasing or `p` is out of range.
41pub fn decode_mut<T: Ord>(xs: &mut [T], mut p: usize) {
42    let n = xs.len();
43    let mut m = crate::factorial(n);
44    debug_assert!(crate::is_ordered_set(xs), "Failed precondition");
45    debug_assert!(p < m, "Failed precondition");
46    for i in 0 .. n {
47        m /= n - i;
48        let j = i + p / m;
49        p %= m;
50        xs[i ..= j].rotate_right(1);
51    }
52    debug_assert_eq!(m, 1);
53    debug_assert_eq!(p, 0);
54}
55
56/// Returns the permutation of the value `p` to the slice `xs`.
57///
58/// The returned permutation can be encoded with [`encode`] to get back `p`.
59///
60/// ```rust
61/// # use number_encoding::factoradics::{decode, encode};
62/// # let xs = [0, 1, 2, 3];
63/// # let p = 15;
64/// let xs = decode(&xs, p);
65/// assert_eq!(encode(&xs), p);
66/// ```
67///
68/// See [`decode_mut`] for a version that applies the permutation to the slice.
69///
70/// # Panics
71///
72/// Panics in debug mode if `xs` is not increasing or `p` is out of range.
73///
74/// # Examples
75///
76/// ```rust
77/// # use number_encoding::factoradics::decode;
78/// assert_eq!(decode(&[0, 1, 2], 0), &[0, 1, 2]);
79/// assert_eq!(decode(&[0, 1, 2], 1), &[0, 2, 1]);
80/// assert_eq!(decode(&[0, 1, 2], 2), &[1, 0, 2]);
81/// ```
82#[cfg(feature = "alloc")]
83pub fn decode<T: Clone + Ord>(xs: &[T], p: usize) -> Vec<T> {
84    let mut xs = xs.to_vec();
85    decode_mut(&mut xs[..], p);
86    xs
87}
88
89#[test]
90fn decode_ok() {
91    fn test(d: usize, p: usize, e: &[usize]) {
92        let mut r: Vec<_> = (0 .. d).collect();
93        decode_mut(&mut r, p);
94        assert_eq!(r, e, "p={p}");
95    }
96    test(0, 0, &[]);
97    test(1, 0, &[0]);
98    test(2, 0, &[0, 1]);
99    test(2, 1, &[1, 0]);
100    test(3, 0, &[0, 1, 2]);
101    test(3, 1, &[0, 2, 1]);
102    test(3, 2, &[1, 0, 2]);
103    test(3, 3, &[1, 2, 0]);
104    test(3, 4, &[2, 0, 1]);
105    test(3, 5, &[2, 1, 0]);
106}
107
108/// Returns the value of a permutation.
109///
110/// The returned value can be decoded with [`decode`] to get back `xs`.
111///
112/// ```rust
113/// # use number_encoding::factoradics::{decode, encode};
114/// # let xs = &[2, 0, 1];
115/// let mut ys = xs.to_vec();
116/// ys.sort();
117/// let p = encode(xs);
118/// assert_eq!(decode(&ys, p), xs);
119/// ```
120///
121/// # Panics
122///
123/// Panics in debug mode if `xs` does not contain distinct elements.
124///
125/// # Examples
126///
127/// ```rust
128/// # use number_encoding::factoradics::encode;
129/// assert_eq!(encode(&[0, 1, 2]), 0);
130/// assert_eq!(encode(&[0, 2, 1]), 1);
131/// assert_eq!(encode(&[1, 0, 2]), 2);
132/// ```
133pub fn encode<T: Ord>(xs: &[T]) -> usize {
134    debug_assert!(crate::is_unordered_set(xs), "Failed precondition");
135    let n = xs.len();
136    let mut m = crate::factorial(n);
137    let mut r = 0;
138    for i in 0 .. n {
139        m /= n - i;
140        r += m * xs[i + 1 ..].iter().filter(|&x| x < &xs[i]).count();
141    }
142    debug_assert_eq!(m, 1);
143    r
144}
145
146#[test]
147fn encode_ok() {
148    fn test(xs: &[usize], p: usize) {
149        assert_eq!(encode(xs), p, "xs={xs:?}");
150    }
151    test(&[], 0);
152    test(&[0], 0);
153    test(&[0, 1], 0);
154    test(&[1, 0], 1);
155    test(&[0, 1, 2], 0);
156    test(&[0, 2, 1], 1);
157    test(&[1, 0, 2], 2);
158    test(&[1, 2, 0], 3);
159    test(&[2, 0, 1], 4);
160    test(&[2, 1, 0], 5);
161}
162
163/// Iterates over all permutations of a slice.
164///
165/// The permutations are iterated in value order:
166///
167/// ```rust
168/// # use number_encoding::factoradics::{Iter, encode};
169/// # let mut xs = [0, 1, 2, 3];
170/// let mut iter = Iter::new(&mut xs);
171/// let mut i = 0;
172/// while let Some(xs) = iter.next() {
173///     assert_eq!(encode(xs), i);
174///     i += 1;
175/// }
176/// ```
177///
178/// If the iteration goes to the end (i.e. [`next`](Iter::next) returns `None`), then the slice is
179/// restored to its initial value (i.e. increasing):
180///
181/// ```rust
182/// # use number_encoding::factoradics::Iter;
183/// # let mut xs = [0, 1, 2, 3];
184/// let saved_xs = xs.clone();
185/// let mut iter = Iter::new(&mut xs);
186/// while iter.next().is_some() {}
187/// assert_eq!(xs, saved_xs);
188/// ```
189///
190/// # Examples
191///
192/// ```rust
193/// # use number_encoding::factoradics::Iter;
194/// # fn process(xs: &[usize]) {}
195/// # let mut xs = [0, 1, 2, 3];
196/// let mut iter = Iter::new(&mut xs);
197/// while let Some(xs) = iter.next() {
198///     process(xs);
199/// }
200/// ```
201pub struct Iter<'a, T> {
202    data: &'a mut [T],
203    state: IterState,
204}
205
206enum IterState {
207    New,
208    Running,
209    Done,
210}
211
212impl<'a, T: Ord> Iter<'a, T> {
213    /// Constructs an iterator with an increasing slice.
214    ///
215    /// # Panics
216    ///
217    /// Panics in debug mode if `xs` is not increasing.
218    pub fn new(xs: &mut [T]) -> Iter<T> {
219        debug_assert!(crate::is_ordered_set(xs));
220        Iter { data: xs, state: IterState::New }
221    }
222
223    /// Returns the next permutation.
224    ///
225    /// If iteration is over, returns `None`.
226    #[allow(clippy::should_implement_trait)]
227    pub fn next(&mut self) -> Option<&[T]> {
228        match self.state {
229            IterState::New => self.state = IterState::Running,
230            IterState::Running => {
231                if self.advance() {
232                    self.state = IterState::Done;
233                }
234            }
235            IterState::Done => (),
236        }
237        match self.state {
238            IterState::New => unreachable!(),
239            IterState::Running => Some(self.data),
240            IterState::Done => None,
241        }
242    }
243
244    fn advance(&mut self) -> bool {
245        let k = self.data.len();
246        if k == 0 {
247            return true;
248        }
249        let mut i = k - 1;
250        while i > 0 && self.data[i - 1] > self.data[i] {
251            i -= 1;
252        }
253        if i == 0 {
254            self.data.reverse();
255            return true;
256        }
257        self.data[i ..].reverse();
258        let j = self.data[i ..].iter().position(|x| x > &self.data[i - 1]).unwrap();
259        self.data.swap(i - 1, i + j);
260        false
261    }
262}
263
264#[test]
265fn iter_ok() {
266    fn test(r: &[&[usize]]) {
267        let mut xs = r[0].to_vec();
268        let mut iter = Iter::new(&mut xs);
269        let mut i = 0;
270        while let Some(xs) = iter.next() {
271            assert_eq!(xs, r[i]);
272            assert_eq!(encode(xs), i);
273            i += 1;
274        }
275        assert_eq!(r.len(), i);
276        assert_eq!(xs, r[0]);
277    }
278    test(&[&[]]);
279    test(&[&[0]]);
280    test(&[&[0, 1], &[1, 0]]);
281    test(&[&[0, 1, 2], &[0, 2, 1], &[1, 0, 2], &[1, 2, 0], &[2, 0, 1], &[2, 1, 0]]);
282    test(&[
283        &[0, 1, 2, 3],
284        &[0, 1, 3, 2],
285        &[0, 2, 1, 3],
286        &[0, 2, 3, 1],
287        &[0, 3, 1, 2],
288        &[0, 3, 2, 1],
289        &[1, 0, 2, 3],
290        &[1, 0, 3, 2],
291        &[1, 2, 0, 3],
292        &[1, 2, 3, 0],
293        &[1, 3, 0, 2],
294        &[1, 3, 2, 0],
295        &[2, 0, 1, 3],
296        &[2, 0, 3, 1],
297        &[2, 1, 0, 3],
298        &[2, 1, 3, 0],
299        &[2, 3, 0, 1],
300        &[2, 3, 1, 0],
301        &[3, 0, 1, 2],
302        &[3, 0, 2, 1],
303        &[3, 1, 0, 2],
304        &[3, 1, 2, 0],
305        &[3, 2, 0, 1],
306        &[3, 2, 1, 0],
307    ]);
308}