Module aoc_search::permutations
source · Expand description
Generate permutations of usize
from 0 .. len
.
The main functionality is provided by the PermutationsHelper
struct.
Designed to be used with a indexed list of items of which to generate permutations, eg in a
Vec
or similar. Provide the number of items when calling PermutationsHelper::new
, then
call next
in a loop, aborting if it returns false
. After
calling next
, the indexes are available by treating this struct
as a slice via the Deref
trait.
Examples
Basic usage:
let mut perms_helper = PermutationsHelper::new (2);
assert_eq! (true, perms_helper.next ());
assert_eq! (& [0, 1], & * perms_helper);
assert_eq! (true, perms_helper.next ());
assert_eq! (& [1, 0], & * perms_helper);
assert_eq! (false, perms_helper.next ());
This struct doesn’t implement Iterator
so that we avoid allocating a Vec
or similar
for every iteration. It can easily be wrapped as one if needed:
let mut perms_helper = PermutationsHelper::new (2);
let mut perms_iter = iter::from_fn (move ||
perms_helper.next ().then (|| perms_helper.to_vec ()));
assert_eq! (Some (vec! [0, 1]), perms_iter.next ());
assert_eq! (Some (vec! [1, 0]), perms_iter.next ());
assert_eq! (None, perms_iter.next ());
A more typical example is generating permutations of indexes into a Vec
, performing a
calculation based on the items in that order, and finally performing some type of search or
aggregation over the results:
let items = vec! [ 49_u64, 93, 51, 45, 26, 73, 20, 80 ];
let mut perms_helper = PermutationsHelper::new (items.len ());
let calc_iter = iter::from_fn (move ||
perms_helper.next ().then (|| perms_helper.iter ()
.map (|& idx| items [idx])
.fold (0, |sum, item| sum * 100 + item)));
assert_eq! (9380735149452620, calc_iter.clone ().max ().unwrap ());
assert_eq! (2026454951738093, calc_iter.clone ().min ().unwrap ());
Algorithm
This implements a “classic” algorithm described on Wikipedia, which produces results in lexicographical order. The alogirthm starts with the items in order, then applies the following steps to generate subsequent iterations:
- Find the highest index
idx_0
whereitems [idx_0] < items [idx_0 + 1]
- Find the highest index
idx_1
whereidx_0 < idx_1 && items [idx_0] < items [idx_1]
- Swap
items [idx_0]
anditems [idx_1]
- Reverse the order of
items [idx_0 + 1 .. ]
Structs
- The
PermutationsHelper
type. See the module level documentation for more information.