permutator/lib.rs
1//! This crate provide generic cartesian product iterator,
2//! combination iterator, and permutation iterator.
3//!
4//! # Three main functionalities
5//! - Cartesian product
6//! - Combination
7//! - Permutation
8//!
9//! # Two different style on every functionality
10//! This crate provide two implementation style
11//! - Iterator style
12//! - Callback function style
13//!
14//! # Easily share result
15//! - Every functionalities can take Rc<RefCell<>> to store result.
16//! - An iterator that return owned value.
17//! - Every callback style function can take Arc<RwLock<>> to store result.
18//!
19//! # Easy usage
20//! Three built-in traits that add cart_prod, combination, and permutation functionality
21//! to slice/array, Rc<RefCell<&mut[T]>>, and more.
22//!
23//! # Unreach raw performance with unsafe
24//! Every functionalities can take raw mutable pointer to store result.
25//!
26//! # Example
27//! - Getting k-permutation where k is 3 and n is 5.
28//! ```
29//! use permutator::{Combination, Permutation};
30//! let mut data = &[1, 2, 3, 4, 5];
31//! let mut counter = 1;
32//! data.combination(3).for_each(|mut c| {
33//! c.permutation().for_each(|p| {
34//! println!("k-permutation@{}={:?}", counter, p);
35//! counter += 1;
36//! });
37//! });
38//! ```
39//! - Getting lexicographically ordered k-permutation where k is 3 and n is 5.
40//! ```
41//! use permutator::{Combination, XPermutationIterator};
42//! let mut data = &[1, 2, 3, 4, 5];
43//! let mut counter = 1;
44//! data.combination(3).for_each(|mut c| {
45//! XPermutationIterator::new(&c, |_| true).for_each(|p| {
46//! println!("k-permutation@{}={:?}", counter, p);
47//! counter += 1;
48//! });
49//! });
50//! ```
51//! - Cartesian product of set of 3, 4, and 5 respectively
52//! ```
53//! use permutator::{CartesianProductIterator, cartesian_product};
54//! let mut domains : &[&[i32]]= &[&[1, 2], &[3, 4, 5], &[6, 7, 8, 9]];
55//! println!("=== Cartesian product iterative style ===");
56//! CartesianProductIterator::new(domains).into_iter().for_each(|p| {
57//! println!("{:?}", p);
58//! });
59//! println!("=== cartesian product callback style ===");
60//! cartesian_product(domains, |p| {
61//! // `p` is borrowed a ref to internal variable inside cartesian_product function.
62//! println!("{:?}", p);
63//! });
64//! ```
65//! - Easy sharable result
66//! ```
67//! use std::cell::RefCell;
68//! use std::rc::Rc;
69//! use std::time::Instant;
70//! use permutator::CartesianProduct;
71//!
72//! let mut counter = 0;
73//! let timer = Instant::now();
74//! let data : &[&[u8]]= &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9]];
75//! let mut result = vec![&data[0][0]; data.len()];
76//! let shared = Rc::new(RefCell::new(result.as_mut_slice()));
77//!
78//! (data, Rc::clone(&shared)).cart_prod().for_each(|_| {
79//! println!("{:?}", &*shared.borrow());
80//! // and notify result borrower(s) that new product is available.
81//!
82//! counter += 1;
83//! });
84//!
85//! println!("Total {} products done in {:?}", counter, timer.elapsed());
86//! ```
87//! - Unsafely share result example
88//! ```
89//! use std::time::Instant;
90//! use permutator::Permutation;
91//!
92//! let data : &[i32] = &[1, 2, 3, 4, 5];
93//! let mut counter = 0;
94//! let k = 3;
95//! let mut result : Vec<&i32> = vec![&data[0]; k];
96//! // `result` can be share safely anywhere
97//! let shared = result.as_mut_slice() as *mut [&i32];
98//! // `shared` can be share as long as `result` is alive
99//! let timer = Instant::now();
100//! // unsafe statement may be omit because the permutation trait
101//! // hid it internally. However, keep in mind that it rely
102//! // on a pointer so every operation is still considered unsafe.
103//! unsafe {
104//! (data, k, shared).permutation().for_each(|_| {
105//! println!("{:?}", &*shared);
106//! // and notify result borrower(s) that new permutation is available.
107//!
108//! counter += 1;
109//! });
110//!
111//! println!("Total {} combination done in {:?}", counter, timer.elapsed());
112//! }
113//! ```
114//! # See
115//! - [Github repository for more examples](https://github.com/NattapongSiri/permutator)
116//!
117//! # Found a bug ?
118//! Open issue at [Github](https://github.com/NattapongSiri/permutator)
119
120extern crate num;
121
122use num::{PrimInt, Unsigned};
123use std::cell::RefCell;
124use std::collections::{VecDeque};
125use std::iter::{Chain, ExactSizeIterator, Iterator, Product, Once, once};
126use std::rc::Rc;
127use std::sync::{Arc, RwLock};
128
129pub mod copy;
130
131/// Calculate all possible cartesian combination size.
132/// It is always equals to size.pow(degree).
133/// # Parameters
134/// - `size` is a size of data to generate a cartesian product
135/// - `degree` is a number of combination of data.
136/// # Examples
137/// ```
138/// use permutator::get_cartesian_size;
139///
140/// get_cartesian_size(3, 2); // return 9.
141/// get_cartesian_size(3, 3); // return 27.
142/// ```
143/// # See
144/// [get_cartesian_for](fn.get_cartesian_for.html)
145pub fn get_cartesian_size(size: usize, degree: usize) -> usize {
146 size.pow(degree as u32)
147}
148
149/// Get a cartesian product at specific location.
150/// If `objects` is [1, 2, 3] and degree is 2 then
151/// all possible result is [1, 1], [1, 2], [1, 3],
152/// [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]
153///
154/// # Parameters
155/// - `objects` is a slice of an object.
156/// - `degree` is a degree of cartesian size.
157/// - `i` is a specific location to get a combination.
158///
159/// # Examples
160/// ```
161/// use permutator::get_cartesian_for;
162///
163/// let nums = [1, 2, 3];
164/// get_cartesian_for(&nums, 2, 0); // Return Ok([1, 1])
165/// get_cartesian_for(&nums, 2, 3); // Return Ok([2, 1])
166/// get_cartesian_for(&nums, 2, 8); // Return Ok([3, 3])
167/// get_cartesian_for(&nums, 2, 9); // Return Err("Parameter `i` is out of bound")
168/// get_cartesian_for(&nums, 4, 0); // Return Err("Parameter `degree` cannot be larger than size of objects")
169/// ```
170pub fn get_cartesian_for<T>(objects: &[T], degree: usize, i: usize) -> Result<Vec<&T>, &str> {
171 if i >= get_cartesian_size(objects.len(), degree) {
172 return Err("Parameter `i` is out of bound")
173 }
174
175 if objects.len() < degree {
176 return Err("Parameter `degree` cannot be larger than size of objects")
177 }
178
179 let w_len = objects.len();
180 let mut result = VecDeque::new();
181 let mut idx = i;
182
183 (0..degree).for_each(|_| {
184 let x = idx % w_len;
185 result.push_front(&objects[x]);
186 idx /= w_len;
187 });
188
189 return Ok(Vec::from(result))
190}
191
192/// Calculate all possible number of permutation.
193/// It's equals to size!/(size - 1).
194///
195/// # Parameters
196/// - `size` a size of data set to generate a permutation.
197/// - `degree` number of data set repetition.
198///
199/// # Examples
200/// ```
201/// use permutator::get_permutation_size;
202///
203/// get_permutation_size(3, 2); // return = 6
204/// get_permutation_size(4, 2); // return = 12
205/// ```
206///
207/// # See
208/// [get_permutation_for](fn.get_permutation_for.html)
209pub fn get_permutation_size(size: usize, degree: usize) -> usize {
210 divide_factorial(size, size - degree)
211}
212
213/// Get permutation at specific location.
214/// If `objects` is [1, 2, 3, 4] and `degree` is 2 then
215/// all possible permutation will be [1, 2], [1, 3],
216/// [1, 4], [2, 1], [2, 3], [2, 4], [3, 1], [3, 2],
217/// [3, 4], [4, 1], [4, 2], [4, 3].
218///
219/// # Parameters
220/// - `objects` a set of data that is a based for permutation.
221/// - `degree` number of element per each location.
222/// - `x` is a location to get a permutation
223///
224/// # Examples
225/// ```
226/// use permutator::get_permutation_for;
227///
228/// let nums = [1, 2, 3, 4];
229/// get_permutation_for(&nums, 2, 0); // return Result([1, 2])
230/// get_permutation_for(&nums, 3, 0); // return Result([1, 2, 3])
231/// get_permutation_for(&nums, 2, 5); // return Result([2, 4])
232/// get_permutation_for(&nums, 2, 11); // return Result([4, 3])
233/// get_permutation_for(&nums, 2, 12); // return Err("parameter x is outside a possible length")
234/// get_permutation_for(&nums, 5, 0); // return Err("Insufficient number of object in parameters objects for given parameter degree")
235/// ```
236pub fn get_permutation_for<T>(objects: &[T], degree: usize, x: usize) -> Result<Vec<&T>, &str> {
237 let mut next_x = x;
238 // hold ordered result for purpose of calculating slot
239 let mut states = Vec::<usize>::with_capacity(degree);
240 // a slot available for next result to check if it fit in.
241 let mut slots = vec!(0; degree);
242 // actual result to return to caller.
243 let mut result = Vec::new();
244
245 if objects.len() < degree {
246 return Err("Insufficient number of object in parameters objects for given parameter degree")
247 }
248
249 if x >= divide_factorial(objects.len(), objects.len() - degree) {
250 return Err("parameter x is outside a possible length");
251 }
252
253 for i in 1..degree + 1 {
254 let div = divide_factorial(objects.len() - i, objects.len() - degree);
255 // raw index that need to be adjusted before adding to result.
256 let mut idx = next_x / div;
257 // update x for next set of value calculation.
258 next_x = next_x % div;
259
260 if i > 1 {
261 let mut counter = idx; // hold slot allocation simulation
262
263 for (j, slot) in slots.iter().enumerate() {
264 if counter < *slot {
265 // found slot that can fit the value
266 idx += j; // offset value for all previous slot(s)
267 result.push(&objects[idx]);
268 break;
269 } else {
270 counter -= slot; // take all the slot
271 }
272 }
273
274 if result.len() < i {
275 // no slot found, appending to result
276 idx = idx + i - 1; // offset for all previous slot(s)
277 result.push(&objects[idx]);
278 }
279
280 let mut insert_point = None;
281
282 // Find where the last value were inserted if result is in ordered.
283 for j in 0..states.len() {
284 if idx < states[j] { // found place to insert value
285 insert_point = Some(j);
286 break;
287 }
288 }
289
290 if let Some(j) = insert_point {
291 // insert value at insertion point
292 states.insert(j, idx);
293 } else {
294 // the value is larger than entire result.
295 states.push(idx); // append value to state as largest one.
296 }
297
298 slots[0] = states[0]; // update first state
299
300 for j in 1..slots.len() { // update slot info
301 if j < states.len() { // found slot required an update
302 // slot size is equals to current state - previous state - 1.
303 slots[j] = states[j] - states[j - 1] - 1;
304 } else { // all slots with associated state updated
305 break;
306 }
307 }
308 } else {
309 // First element.
310 result.push(&objects[idx]);
311 states.push(idx);
312 slots[0] = idx - 0;
313 }
314 }
315
316 Ok(result)
317}
318
319/// Core algorithm to generate cartesian product.
320/// # Parameters
321/// - `n` - the size of domains.
322/// For product on self, it equals to how many time to create product on self.
323/// - `set_len` - the closure to get length of each domain.
324/// - `assign_res` - the closure to store product into result
325/// - `cb` - the closure to get call on each generated product.
326/// # Execution sequence of closure.
327/// Each step in sequence is performed sequentially.
328/// It won't advance if the closure in given step isn't return.
329/// 1. `assign_res` once
330/// 2. `cb` once
331/// 3. `set_len` multiple times until it found at least a domain
332/// that doesn't exhausted, otherwise, terminate function.
333/// 4. go back to step 1
334#[inline(always)]
335fn _cartesian_product_core<R, S>(
336 n : usize,
337 set_len : impl Fn(usize) -> usize,
338 mut assign_res : impl FnMut(usize, usize) -> R,
339 mut cb : impl FnMut() -> S)
340{
341 assert!(n > 0, "Cannot create cartesian product with number of domain == 0");
342
343 let mut more = true;
344 let mut i = 0;
345 let mut c = vec![0; n];
346 let n = n - 1;
347 while more {
348 assign_res(i, c[i]);
349
350 if i == n {
351 c[i] += 1;
352 cb();
353 }
354
355 if i < n {
356 i += 1;
357 }
358
359 while c[i] == set_len(i) { // c[i] reach the length of set[i]
360 c[i] = 0;
361
362 if i == 0 {
363 more = false;
364 break;
365 }
366
367 i -= 1;
368 c[i] += 1;
369 }
370
371 }
372}
373
374/// Create a cartesian product over given slice. The result will be a slice
375/// of borrowed `T`.
376///
377/// # Parameters
378/// - `sets` A slice of slice(s) contains `T` elements.
379/// - `cb` A callback function. It will be called on each product.
380///
381/// # Return
382/// A function return a slice of borrowed `T` element out of parameter `sets`.
383/// It return value as parameter of callback function `cb`.
384///
385/// # Examples
386/// To print all cartesian product between [1, 2, 3] and [4, 5, 6].
387/// ```
388/// use permutator::cartesian_product;
389///
390/// cartesian_product(&[&[1, 2, 3], &[4, 5, 6]], |product| {
391/// // First called will receive [1, 4] then [1, 5] then [1, 6]
392/// // then [2, 4] then [2, 5] and so on until [3, 6].
393/// println!("{:?}", product);
394/// });
395/// ```
396pub fn cartesian_product<'a, T, F>(
397 sets : &'a [&[T]],
398 mut cb : F)
399where T : 'a,
400 for<'r> F : FnMut(&'r [&'a T]) + 'a
401{
402 let mut result = vec![&sets[0][0]; sets.len()];
403 let copied = result.as_slice() as *const [&T];
404 unsafe {
405 // It'd safe to use pointer here because internally,
406 // the callback will be called after result mutation closure
407 // and it will wait until the callback function return to
408 // resume mutate the result again.
409 _cartesian_product_core(
410 sets.len(),
411 #[inline(always)] |i| {
412 sets[i].len()
413 },
414 #[inline(always)] |i, c| {
415 result[i] = &sets[i][c];
416 },
417 #[inline(always)] || {
418 cb(&*copied);
419 });
420 }
421}
422
423/// Similar to safe [cartesian_product function](fn.cartesian_product.html)
424/// except the way it return the product.
425/// It return result through mutable pointer to result assuming the
426/// pointer is valid. It'll notify caller on each new result via empty
427/// callback function.
428/// # Parameters
429/// - `sets` A raw sets of data to get a cartesian product.
430/// - `result` A mutable pointer to slice of length equals to `sets.len()`
431/// - `cb` A callback function which will be called after new product
432/// in `result` is set.
433/// # Return
434/// This function return result through function's parameter `result` and
435/// notify caller that new result is available through `cb` callback function.
436/// # Unsafe
437/// This function is unsafe because it may dereference a dangling pointer,
438/// may cause data race if multiple threads read/write to the same memory,
439/// and all of those unsafe Rust condition will be applied here.
440/// # Rationale
441/// The safe [cartesian_product function](fn.cartesian_product.html)
442/// return value in callback parameter. It limit the lifetime of return
443/// product to be valid only inside it callback. To use it outside
444/// callback scope, it need to copy the value which will have performance
445/// penalty. Therefore, jeopardize it own goal of being fast. This
446/// function provide alternative way that sacrifice safety for performance.
447///
448/// # Example
449/// The scenario is we want to get cartesian product from single source of data
450/// then distribute the product to two workers which read each combination
451/// then do something about it, which in this example, simply print it.
452/// ```
453/// use permutator::unsafe_cartesian_product;
454/// use std::fmt::Debug;
455/// // All shared data consumer will get call throught this trait
456/// trait Consumer {
457/// fn consume(&self); // need to be ref due to rule of only ref mut is permit at a time
458/// }
459///
460/// struct Worker1<'a, T : 'a> {
461/// data : &'a[&'a T] // Store ref to cartesian product.
462/// }
463///
464/// impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
465/// fn consume(&self) {
466/// // read new share cartesian product and do something about it, in this case simply print it.
467/// println!("Work1 has {:?}", self.data);
468/// }
469/// }
470///
471/// struct Worker2<'a, T : 'a> {
472/// data : &'a[&'a T] // Store ref to cartesian product.
473/// }
474///
475/// impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
476/// fn consume(&self) {
477/// // read new share cartesian product and do something about it, in this case simply print it.
478/// println!("Work2 has {:?}", self.data);
479/// }
480/// }
481///
482/// unsafe fn start_cartesian_product_process<'a>(data : &'a[&'a[i32]], cur_result : *mut [&'a i32], consumers : Vec<Box<Consumer + 'a>>) {
483/// unsafe_cartesian_product(data, cur_result, || {
484/// consumers.iter().for_each(|c| {
485/// c.consume();
486/// })
487/// });
488/// }
489///
490/// let data : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6]];
491/// let mut result = vec![&data[0][0]; data.len()];
492///
493/// unsafe {
494///
495/// let shared = result.as_mut_slice() as *mut [&i32];
496/// let worker1 = Worker1 {
497/// data : &result
498/// };
499/// let worker2 = Worker2 {
500/// data : &result
501/// };
502/// let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
503/// start_cartesian_product_process(data, shared, consumers);
504/// }
505/// ```
506/// # See
507/// - [cartesian_product function](fn.cartesian_product.html)
508pub unsafe fn unsafe_cartesian_product<'a, T>(sets : &'a[&[T]], result : *mut [&'a T], cb : impl FnMut()) {
509 _cartesian_product_core(
510 sets.len(),
511 #[inline(always)] |i| {
512 sets[i].len()
513 },
514 #[inline(always)] |i, c| {
515 (*result)[i] = &sets[i][c];
516 }, cb);
517}
518
519/// Similar to safe [cartesian_product function](fn.cartesian_product.html)
520/// except the way it return the product.
521/// It return result through Rc<RefCell<>> to mutable slice of result.
522/// It'll notify caller on each new result via empty callback function.
523/// # Parameters
524/// - `sets` A raw sets of data to get a cartesian product.
525/// - `result` An Rc<RefCell<>> contains mutable slice of length equals to `sets.len()`
526/// - `cb` A callback function which will be called after new product
527/// in `result` is set.
528/// # Return
529/// This function return result through function's parameter `result` and
530/// notify caller that new result is available through `cb` callback function.
531/// # Rationale
532/// The safe [cartesian product function](fn.cartesian_product.html) return value in
533/// callback parameter. It limit the lifetime of return combination to be
534/// valid only inside it callback. To use it outside callback scope, it
535/// need to copy the value which will have performance penalty. Therefore,
536/// jeopardize it own goal of being fast. This function provide alternative
537/// safe way to share result which is roughly 50% slower to unsafe counterpart.
538/// The performance is on par with using [CartesianProduct](struct.CartesianProductIterator.html#method.next_into_cell)
539/// iterator.
540///
541/// # Example
542/// The scenario is we want to get cartesian product from single source of data
543/// then distribute the product to two workers which read each combination
544/// then do something about it, which in this example, simply print it.
545/// ```
546/// use permutator::cartesian_product_cell;
547/// use std::fmt::Debug;
548/// use std::rc::Rc;
549/// use std::cell::RefCell;
550///
551/// // All shared data consumer will get call throught this trait
552/// trait Consumer {
553/// fn consume(&self); // need to be ref due to rule of only ref mut is permit at a time
554/// }
555///
556/// struct Worker1<'a, T : 'a> {
557/// data : Rc<RefCell<&'a mut[&'a T]>> // Store ref to cartesian product.
558/// }
559///
560/// impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
561/// fn consume(&self) {
562/// // read new share cartesian product and do something about it, in this case simply print it.
563/// println!("Work1 has {:?}", self.data.borrow());
564/// }
565/// }
566///
567/// struct Worker2<'a, T : 'a> {
568/// data : Rc<RefCell<&'a mut[&'a T]>> // Store ref to cartesian product.
569/// }
570///
571/// impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
572/// fn consume(&self) {
573/// // read new share cartesian product and do something about it, in this case simply print it.
574/// println!("Work2 has {:?}", self.data.borrow());
575/// }
576/// }
577///
578/// fn start_cartesian_product_process<'a>(data : &'a[&'a[i32]], cur_result : Rc<RefCell<&'a mut [&'a i32]>>, consumers : Vec<Box<Consumer + 'a>>) {
579/// cartesian_product_cell(data, cur_result, || {
580/// consumers.iter().for_each(|c| {
581/// c.consume();
582/// })
583/// });
584/// }
585///
586/// let data : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6]];
587/// let mut result = vec![&data[0][0]; data.len()];
588///
589/// let shared = Rc::new(RefCell::new(result.as_mut_slice()));
590/// let worker1 = Worker1 {
591/// data : Rc::clone(&shared)
592/// };
593/// let worker2 = Worker2 {
594/// data : Rc::clone(&shared)
595/// };
596/// let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
597/// start_cartesian_product_process(data, shared, consumers);
598/// ```
599/// # See
600/// - [cartesian_product function](fn.cartesian_product.html)
601pub fn cartesian_product_cell<'a, T>(sets : &'a[&[T]], result : Rc<RefCell<&'a mut [&'a T]>>, cb : impl FnMut()) {
602 _cartesian_product_core(
603 sets.len(),
604 #[inline(always)] |i| {
605 sets[i].len()
606 },
607 #[inline(always)] |i, c| {
608 result.borrow_mut()[i] = &sets[i][c];
609 }, cb);
610}
611
612/// Similar to safe [cartesian_product function](fn.cartesian_product.html)
613/// except the way it return the product.
614/// It return result through Rc<RefCell<>> to mutable slice of result.
615/// It'll notify caller on each new result via empty callback function.
616/// # Parameters
617/// - `sets` A raw sets of data to get a cartesian product.
618/// - `result` An Rc<RefCell<>> contains mutable slice of length equals to `sets.len()`
619/// - `cb` A callback function which will be called after new product
620/// in `result` is set.
621/// # Return
622/// This function return result through function's parameter `result` and
623/// notify caller that new result is available through `cb` callback function.
624/// # Rationale
625/// The safe [cartesian product function](fn.cartesian_product.html) return value in
626/// callback parameter. It limit the lifetime of return combination to be
627/// valid only inside it callback. To use it outside callback scope, it
628/// need to copy the value which will have performance penalty. Therefore,
629/// jeopardize it own goal of being fast. This function provide alternative
630/// safe way to share result which is roughly 50% slower to unsafe counterpart.
631/// The performance is on roughly 15%-20% slower than [CartesianProduct](struct.CartesianProductIterator.html)
632/// iterator in uncontrol test environment.
633///
634/// # Example
635/// The scenario is we want to get cartesian product from single source of data
636/// then distribute the product to two workers which read each combination
637/// then do something about it, which in this example, simply print it.
638/// ```
639/// use std::thread;
640/// use std::sync::{Arc, RwLock};
641/// use std::sync::mpsc;
642/// use std::sync::mpsc::{Receiver, SyncSender};
643/// use permutator::cartesian_product_sync;
644///
645/// fn start_cartesian_product_process<'a>(data : &'a[&[i32]], cur_result : Arc<RwLock<Vec<&'a i32>>>, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
646/// use std::time::Instant;
647/// let timer = Instant::now();
648/// let mut counter = 0;
649/// cartesian_product_sync(data, cur_result, || {
650/// notifier.iter().for_each(|n| {
651/// n.send(Some(())).unwrap(); // notify every thread that new data available
652/// });
653///
654/// for _ in 0..notifier.len() {
655/// release_recv.recv().unwrap(); // block until all thread reading data notify on read completion
656/// }
657///
658/// counter += 1;
659/// });
660///
661/// notifier.iter().for_each(|n| {n.send(None).unwrap()}); // notify every thread that there'll be no more data.
662///
663/// println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
664/// }
665/// let k = 7;
666/// let data : &[&[i32]]= &[&[1, 2, 3], &[4, 5], &[6]];
667/// let result = vec![&data[0][0]; k];
668/// let result_sync = Arc::new(RwLock::new(result));
669///
670/// // workter thread 1
671/// let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
672/// let (main_send, main_recv) = mpsc::sync_channel(0);
673/// let t1_local = main_send.clone();
674/// let t1_dat = Arc::clone(&result_sync);
675/// thread::spawn(move || {
676/// while let Some(_) = t1_recv.recv().unwrap() {
677/// let result : &Vec<&i32> = &*t1_dat.read().unwrap();
678/// // println!("Thread1: {:?}", result);
679/// t1_local.send(()).unwrap(); // notify generator thread that reference is no longer need.
680/// }
681/// println!("Thread1 is done");
682/// });
683///
684/// // worker thread 2
685/// let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
686/// let t2_dat = Arc::clone(&result_sync);
687/// let t2_local = main_send.clone();
688/// thread::spawn(move || {
689/// while let Some(_) = t2_recv.recv().unwrap() {
690/// let result : &Vec<&i32> = &*t2_dat.read().unwrap();
691/// // println!("Thread2: {:?}", result);
692/// t2_local.send(()).unwrap(); // notify generator thread that reference is no longer need.
693/// }
694/// println!("Thread2 is done");
695/// });
696///
697/// // main thread that generate result
698/// thread::spawn(move || {
699/// start_cartesian_product_process(data, result_sync, vec![t1_send, t2_send], main_recv);
700/// }).join().unwrap();
701/// ```
702/// # See
703/// - [cartesian_product function](fn.cartesian_product.html)
704pub fn cartesian_product_sync<'a, T>(sets : &'a[&[T]], result : Arc<RwLock<Vec<&'a T>>>, cb : impl FnMut()) {
705 _cartesian_product_core(
706 sets.len(),
707 #[inline(always)] |i| {
708 sets[i].len()
709 },
710 #[inline(always)] |i, c| {
711 result.write().unwrap()[i] = &sets[i][c];
712 }, cb);
713}
714
715/// Create a cartesian product over itself. The result will be a slice
716/// of borrowed `T`.
717///
718/// # Parameters
719/// - `set` A slice of slice(s) contains `T` elements.
720/// - `n` How many time to create a product over `set`
721/// - `cb` A callback function. It will be called on each product.
722///
723/// # Return
724/// A function return a slice of borrowed `T` element out of parameter `sets`.
725/// It return value as parameter of callback function `cb`.
726///
727/// # Examples
728/// To print all cartesian product between [1, 2, 3] and [4, 5, 6].
729/// ```
730/// use permutator::self_cartesian_product;
731///
732/// self_cartesian_product(&[1, 2, 3], 3, |product| {
733/// // First called will receive [1, 4] then [1, 5] then [1, 6]
734/// // then [2, 4] then [2, 5] and so on until [3, 6].
735/// println!("{:?}", product);
736/// });
737/// ```
738pub fn self_cartesian_product<'a, T, F>(set : &'a [T], n : usize, mut cb : F)
739where T : 'a,
740 for<'r> F : FnMut(&'r [&'a T]) + 'a
741{
742 let mut result = vec![&set[0]; n];
743
744 let copied = result.as_slice() as *const [&T];
745
746 unsafe {
747 // It'd safe to use pointer here because internally,
748 // the callback will be called after result mutation closure
749 // and it will wait until the callback function return to
750 // resume mutate the result again.
751 _cartesian_product_core(
752 n,
753 #[inline(always)] |_| {
754 set.len()
755 },
756 #[inline(always)] |i, c| {
757 result[i] = &set[c];
758 },
759 #[inline(always)] || {
760 cb(&*copied);
761 });
762 }
763}
764
765/// Similar to safe [self_cartesian_product function](fn.self_cartesian_product.html)
766/// except the way it return the product.
767/// It return result through mutable pointer to result assuming the
768/// pointer is valid. It'll notify caller on each new result via empty
769/// callback function.
770/// # Parameters
771/// - `set` A raw sets of data to get a cartesian product.
772/// - `n` How many time to create a product on `set` parameter.
773/// - `result` A mutable pointer to slice of length equals to `sets.len()`
774/// - `cb` A callback function which will be called after new product
775/// in `result` is set.
776/// # Return
777/// This function return result through function's parameter `result` and
778/// notify caller that new result is available through `cb` callback function.
779/// # Unsafe
780/// This function is unsafe because it may dereference a dangling pointer,
781/// may cause data race if multiple threads read/write to the same memory,
782/// and all of those unsafe Rust condition will be applied here.
783/// # Rationale
784/// The safe [self_cartesian_product function](fn.self_cartesian_product.html)
785/// return value in callback parameter. It limit the lifetime of return
786/// product to be valid only inside it callback. To use it outside
787/// callback scope, it need to copy the value which will have performance
788/// penalty. Therefore, jeopardize it own goal of being fast. This
789/// function provide alternative way that sacrifice safety for performance.
790///
791/// # Example
792/// The scenario is we want to get cartesian product from single source of data
793/// then distribute the product to two workers which read each combination
794/// then do something about it, which in this example, simply print it.
795/// ```
796/// use permutator::unsafe_self_cartesian_product;
797/// use std::fmt::Debug;
798/// // All shared data consumer will get call throught this trait
799/// trait Consumer {
800/// fn consume(&self); // need to be ref due to rule of only ref mut is permit at a time
801/// }
802///
803/// struct Worker1<'a, T : 'a> {
804/// data : &'a[&'a T] // Store ref to cartesian product.
805/// }
806///
807/// impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
808/// fn consume(&self) {
809/// // read new share cartesian product and do something about it, in this case simply print it.
810/// println!("Work1 has {:?}", self.data);
811/// }
812/// }
813///
814/// struct Worker2<'a, T : 'a> {
815/// data : &'a[&'a T] // Store ref to cartesian product.
816/// }
817///
818/// impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
819/// fn consume(&self) {
820/// // read new share cartesian product and do something about it, in this case simply print it.
821/// println!("Work2 has {:?}", self.data);
822/// }
823/// }
824///
825/// unsafe fn start_cartesian_product_process<'a>(data : &'a[i32], n : usize, cur_result : *mut [&'a i32], consumers : Vec<Box<Consumer + 'a>>) {
826/// unsafe_self_cartesian_product(data, n, cur_result, || {
827/// consumers.iter().for_each(|c| {
828/// c.consume();
829/// })
830/// });
831/// }
832///
833/// let data : &[i32] = &[1, 2, 3];
834/// let n = 3;
835/// let mut result = vec![&data[0]; n];
836///
837/// unsafe {
838///
839/// let shared = result.as_mut_slice() as *mut [&i32];
840/// let worker1 = Worker1 {
841/// data : &result
842/// };
843/// let worker2 = Worker2 {
844/// data : &result
845/// };
846/// let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
847/// start_cartesian_product_process(data, n, shared, consumers);
848/// }
849/// ```
850/// # See
851/// - [cartesian_product function](fn.cartesian_product.html)
852pub unsafe fn unsafe_self_cartesian_product<'a, T>(set : &'a[T], n : usize, result : *mut [&'a T], cb : impl FnMut()) {
853 _cartesian_product_core(
854 n,
855 #[inline(always)] |_| {
856 set.len()
857 },
858 #[inline(always)] |i, c| {
859 (*result)[i] = &set[c];
860 }, cb);
861}
862
863/// Similar to safe [cartesian_product function](fn.self_cartesian_product.html)
864/// except the way it return the product.
865/// It return result through Rc<RefCell<>> to mutable slice of result.
866/// It'll notify caller on each new result via empty callback function.
867/// # Parameters
868/// - `set` A raw sets of data to get a cartesian product.
869/// - `n` How many time to create a product of `set` parameter
870/// - `result` An Rc<RefCell<>> contains mutable slice of length equals to `sets.len()`
871/// - `cb` A callback function which will be called after new product
872/// in `result` is set.
873/// # Return
874/// This function return result through function's parameter `result` and
875/// notify caller that new result is available through `cb` callback function.
876/// # Rationale
877/// The safe [cartesian product function](fn.cartesian_product.html) return value in
878/// callback parameter. It limit the lifetime of return combination to be
879/// valid only inside it callback. To use it outside callback scope, it
880/// need to copy the value which will have performance penalty. Therefore,
881/// jeopardize it own goal of being fast. This function provide alternative
882/// safe way to share result which is roughly 50% slower to unsafe counterpart.
883/// The performance is on par with using [CartesianProduct](struct.CartesianProductIterator.html#method.next_into_cell)
884/// iterator.
885///
886/// # Example
887/// The scenario is we want to get cartesian product from single source of data
888/// then distribute the product to two workers which read each combination
889/// then do something about it, which in this example, simply print it.
890/// ```
891/// use permutator::self_cartesian_product_cell;
892/// use std::fmt::Debug;
893/// use std::rc::Rc;
894/// use std::cell::RefCell;
895///
896/// // All shared data consumer will get call throught this trait
897/// trait Consumer {
898/// fn consume(&self); // need to be ref due to rule of only ref mut is permit at a time
899/// }
900///
901/// struct Worker1<'a, T : 'a> {
902/// data : Rc<RefCell<&'a mut[&'a T]>> // Store ref to cartesian product.
903/// }
904///
905/// impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
906/// fn consume(&self) {
907/// // read new share cartesian product and do something about it, in this case simply print it.
908/// println!("Work1 has {:?}", self.data.borrow());
909/// }
910/// }
911///
912/// struct Worker2<'a, T : 'a> {
913/// data : Rc<RefCell<&'a mut[&'a T]>> // Store ref to cartesian product.
914/// }
915///
916/// impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
917/// fn consume(&self) {
918/// // read new share cartesian product and do something about it, in this case simply print it.
919/// println!("Work2 has {:?}", self.data.borrow());
920/// }
921/// }
922///
923/// fn start_cartesian_product_process<'a>(data : &'a[i32], n : usize, cur_result : Rc<RefCell<&'a mut [&'a i32]>>, consumers : Vec<Box<Consumer + 'a>>) {
924/// self_cartesian_product_cell(data, n, cur_result, || {
925/// consumers.iter().for_each(|c| {
926/// c.consume();
927/// })
928/// });
929/// }
930///
931/// let data : &[i32] = &[1, 2, 3];
932/// let n = 3;
933/// let mut result = vec![&data[0]; n];
934///
935/// let shared = Rc::new(RefCell::new(result.as_mut_slice()));
936/// let worker1 = Worker1 {
937/// data : Rc::clone(&shared)
938/// };
939/// let worker2 = Worker2 {
940/// data : Rc::clone(&shared)
941/// };
942/// let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
943/// start_cartesian_product_process(data, n, shared, consumers);
944/// ```
945/// # See
946/// - [cartesian_product function](fn.cartesian_product.html)
947pub fn self_cartesian_product_cell<'a, T>(set : &'a[T], n : usize, result : Rc<RefCell<&'a mut [&'a T]>>, cb : impl FnMut()) {
948 _cartesian_product_core(
949 n,
950 #[inline(always)] |_| {
951 set.len()
952 },
953 #[inline(always)] |i, c| {
954 result.borrow_mut()[i] = &set[c];
955 }, cb);
956}
957
958/// Similar to safe [self_cartesian_product function](fn.self_cartesian_product.html)
959/// except the way it return the product.
960/// It return result through Arc<RwLock<>> to mutable slice of result.
961/// It'll notify caller on each new result via empty callback function.
962/// # Parameters
963/// - `set` A raw set of data to get a cartesian product.
964/// - `n` how many times to do the product of `set` parameter
965/// - `result` An Arc<RwLock<>> contains mutable slice of length equals to parameter `n`
966/// - `cb` A callback function which will be called after new product
967/// in `result` is set.
968/// # Return
969/// This function return result through function's parameter `result` and
970/// notify caller that new result is available through `cb` callback function.
971/// # Rationale
972/// The safe [cartesian product function](fn.self_cartesian_product.html) return value in
973/// callback parameter. It limit the lifetime of return combination to be
974/// valid only inside it callback. To use it outside callback scope, it
975/// need to copy the value which will have performance penalty. Therefore,
976/// jeopardize it own goal of being fast. This function provide alternative
977/// safe way to share result which is roughly 50% slower to unsafe counterpart.
978/// The performance is on roughly 15%-20% slower than [SelfCartesianProduct](struct.SelfCartesianProductIterator.html)
979/// iterator in uncontrol test environment.
980///
981/// # Example
982/// The scenario is we want to get cartesian product from single source of data
983/// then distribute the product to two workers which read each combination
984/// then do something about it, which in this example, simply print it.
985/// ```
986/// use std::thread;
987/// use std::sync::{Arc, RwLock};
988/// use std::sync::mpsc;
989/// use std::sync::mpsc::{Receiver, SyncSender};
990/// use permutator::self_cartesian_product_sync;
991///
992/// fn start_cartesian_product_process<'a>(data : &'a[i32], n : usize, cur_result : Arc<RwLock<Vec<&'a i32>>>, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
993/// use std::time::Instant;
994/// let timer = Instant::now();
995/// let mut counter = 0;
996/// self_cartesian_product_sync(data, n, cur_result, || {
997/// notifier.iter().for_each(|n| {
998/// n.send(Some(())).unwrap(); // notify every thread that new data available
999/// });
1000///
1001/// for _ in 0..notifier.len() {
1002/// release_recv.recv().unwrap(); // block until all thread reading data notify on read completion
1003/// }
1004///
1005/// counter += 1;
1006/// });
1007///
1008/// notifier.iter().for_each(|n| {n.send(None).unwrap()}); // notify every thread that there'll be no more data.
1009///
1010/// println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
1011/// }
1012///
1013/// let data : &[i32]= &[1, 2, 3];
1014/// let n = 3;
1015/// let result = vec![&data[0]; n];
1016/// let result_sync = Arc::new(RwLock::new(result));
1017///
1018/// // workter thread 1
1019/// let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
1020/// let (main_send, main_recv) = mpsc::sync_channel(0);
1021/// let t1_local = main_send.clone();
1022/// let t1_dat = Arc::clone(&result_sync);
1023/// thread::spawn(move || {
1024/// while let Some(_) = t1_recv.recv().unwrap() {
1025/// let result : &Vec<&i32> = &*t1_dat.read().unwrap();
1026/// // println!("Thread1: {:?}", result);
1027/// t1_local.send(()).unwrap(); // notify generator thread that reference is no longer need.
1028/// }
1029/// println!("Thread1 is done");
1030/// });
1031///
1032/// // worker thread 2
1033/// let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
1034/// let t2_dat = Arc::clone(&result_sync);
1035/// let t2_local = main_send.clone();
1036/// thread::spawn(move || {
1037/// while let Some(_) = t2_recv.recv().unwrap() {
1038/// let result : &Vec<&i32> = &*t2_dat.read().unwrap();
1039/// // println!("Thread2: {:?}", result);
1040/// t2_local.send(()).unwrap(); // notify generator thread that reference is no longer need.
1041/// }
1042/// println!("Thread2 is done");
1043/// });
1044///
1045/// // main thread that generate result
1046/// thread::spawn(move || {
1047/// start_cartesian_product_process(data, n, result_sync, vec![t1_send, t2_send], main_recv);
1048/// }).join().unwrap();
1049/// ```
1050/// # See
1051/// - [cartesian_product function](fn.cartesian_product.html)
1052pub fn self_cartesian_product_sync<'a, T>(set : &'a[T], n : usize, result : Arc<RwLock<Vec<&'a T>>>, cb : impl FnMut()) {
1053 _cartesian_product_core(
1054 n,
1055 #[inline(always)] |_| {
1056 set.len()
1057 },
1058 #[inline(always)] |i, c| {
1059 result.write().unwrap()[i] = &set[c];
1060 }, cb);
1061}
1062
1063/// # Deprecated
1064/// This combination family is now deprecated.
1065/// Consider using [large_combination function](fn.large_combination.html)
1066/// instead. This is because current implementation need to copy every ref
1067/// on every iteration which is inefficient.
1068/// On uncontroll test environment, this iterator take 2.41s to iterate over
1069/// 30,045,015 combinations. The [large_combination function](fn.large_combination.html)
1070/// took only 208.84ms. Beside speed, it also theoritically support up to 2^32 elements.
1071/// If no more efficient implementation is available for some certain time period,
1072/// this function will be officially mark with #[deprecated].
1073///
1074/// Generate a combination out of given `domain`.
1075/// It call `cb` to several times to return each combination.
1076/// It's similar to [struct GosperCombination](struct.GosperCombinationIterator.html) but
1077/// slightly faster in uncontrol test environment.
1078/// # Parameters
1079/// - `domain` is a slice containing the source data, AKA 'domain'
1080/// - `r` is a size of each combination, AKA 'range' size
1081/// - `cb` is a callback function that will get call several times.
1082/// Each call will have a slice of combination pass as callback parameter.
1083/// # Returns
1084/// The function will return combination via callback function. It will
1085/// keep calling until no further combination can be found then it
1086/// return control to called.
1087/// # Example
1088/// ```
1089/// use permutator::combination;
1090/// combination(&[1, 2, 3, 4, 5], 3, |c| {
1091/// // called multiple times.
1092/// // Each call have [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]
1093/// // [1, 2, 5], [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5],
1094/// // and [3, 4, 5] respectively.
1095/// println!("{:?}", c);
1096/// });
1097/// ```
1098/// # Limitation
1099/// Gosper algorithm need to know the MSB (most significant bit).
1100/// The current largest known MSB data type is u128.
1101/// This make the implementation support up to 128 elements slice.
1102/// # See
1103/// - [GosperCombination](struct.GospoerCombination.html)
1104pub fn combination<T>(domain: &[T], r : usize, mut cb : impl FnMut(&[&T]) -> ()) {
1105 let (mut combination, mut map) = create_k_set(domain, r);
1106 cb(&combination);
1107
1108 while let Some(_) = swap_k((&mut combination, &mut map), domain) {
1109 cb(&combination);
1110 }
1111}
1112
1113/// # Deprecated
1114/// See [combination function](fn.combination.html) for reason of
1115/// deprecation
1116///
1117/// Similar to safe [combination function](fn.combination.html) except
1118/// the way it return the combination.
1119/// It return result through mutable pointer to result assuming the
1120/// pointer is valid. It'll notify caller on each new result via empty
1121/// callback function.
1122/// # Parameters
1123/// - `domain` A raw data to get combination.
1124/// - `r` A size of each combination.
1125/// - `result` A mutable pointer to slice of length equals to `r`
1126/// - `cb` A callback function which will be called after new combination
1127/// in `result` is set.
1128/// # Return
1129/// This function return result through function's parameter `result` and
1130/// notify caller that new result is available through `cb` callback function.
1131/// # Unsafe
1132/// This function is unsafe because it may dereference a dangling pointer,
1133/// may cause data race if multiple threads read/write to the same memory,
1134/// and all of those unsafe Rust condition will be applied here.
1135/// # Rationale
1136/// The safe [combination function](fn.combination.html) return value in
1137/// callback parameter. It limit the lifetime of return combination to be
1138/// valid only inside it callback. To use it outside callback scope, it
1139/// need to copy the value which will have performance penalty. Therefore,
1140/// jeopardize it own goal of being fast. This function provide alternative
1141/// way that sacrifice safety for performance.
1142/// # Example
1143/// The scenario is we want to get combination from single source of data
1144/// then distribute the combination to two workers which read each combination
1145/// then do something about it, which in this example, simply print it.
1146///
1147/// ```
1148/// use permutator::unsafe_combination;
1149/// use std::fmt::Debug;
1150/// // define a trait that represent a data consumer
1151/// trait Consumer {
1152/// fn consume(&self); // cannot mut data because rule of no more than 1 ref mut at a time.
1153/// }
1154///
1155/// struct Worker1<'a, T : 'a> {
1156/// data : &'a[&'a T] // A reference to each combination
1157/// }
1158///
1159/// impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
1160/// fn consume(&self) {
1161/// // Read data then do something about it. In this case, simply print it.
1162/// println!("Work1 has {:?}", self.data);
1163/// }
1164/// }
1165///
1166/// struct Worker2<'a, T : 'a> {
1167/// data : &'a[&'a T] // A reference to each combination
1168/// }
1169///
1170/// impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
1171/// fn consume(&self) {
1172/// // Read data then do something about it. In this case, simply print it.
1173/// println!("Work2 has {:?}", self.data);
1174/// }
1175/// }
1176///
1177/// unsafe fn start_combination_process<'a>(data : &'a[i32], cur_result : *mut [&'a i32], k : usize, consumers : Vec<Box<Consumer + 'a>>) {
1178/// unsafe_combination(data, k, cur_result, || {
1179/// consumers.iter().for_each(|c| {
1180/// c.consume();
1181/// })
1182/// });
1183/// }
1184/// let k = 3;
1185/// let data = &[1, 2, 3, 4, 5];
1186/// let mut result = vec![&data[0]; k];
1187///
1188/// unsafe {
1189///
1190/// let shared = result.as_mut_slice() as *mut [&i32];
1191/// let worker1 = Worker1 {
1192/// data : &result
1193/// };
1194/// let worker2 = Worker2 {
1195/// data : &result
1196/// };
1197/// let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
1198/// start_combination_process(data, shared, k, consumers);
1199/// }
1200/// ```
1201/// # See
1202/// - [combination function](fn.combination.html)
1203pub unsafe fn unsafe_combination<'a, T>(domain: &'a[T], r : usize, result : *mut [&'a T], mut cb : impl FnMut() -> ()) {
1204 let mut mask = 0u128;
1205 unsafe_create_k_set(domain, r, result, &mut mask);
1206 cb();
1207
1208 while let Some(_) = swap_k((&mut *result, &mut mask), domain) {
1209 cb();
1210 }
1211}
1212
1213/// # Deprecated
1214/// See [combination function](fn.combination.html) for reason of
1215/// deprecation
1216///
1217/// Similar to [combination function](fn.combination.html) except
1218/// the way it return the combination.
1219/// It return result through Rc<RefCell<>> to mutable slice of result.
1220/// It'll notify caller on each new result via empty callback function.
1221/// # Parameters
1222/// - `domain` A raw data to get combination.
1223/// - `r` A size of each combination.
1224/// - `result` An Rc<RefCell<>> to mutable slice of length equals to `r`
1225/// - `cb` A callback function which will be called after new combination
1226/// in `result` is set.
1227/// # Return
1228/// This function return result through function's parameter `result` and
1229/// notify caller that new result is available through `cb` callback function.
1230/// # Rationale
1231/// The safe [combination function](fn.combination.html) return value in
1232/// callback parameter. It limit the lifetime of return combination to be
1233/// valid only inside it callback. To use it outside callback scope, it
1234/// need to copy the value which will have performance penalty. Therefore,
1235/// jeopardize it own goal of being fast. This function provide alternative
1236/// safe way to share result which is roughly 50% slower to unsafe counterpart.
1237/// The performance is on par with using
1238/// [GosperCombinationIterator with next_into_cell function](struct.GosperCombinationIterator.html#method.next_into_cell).
1239/// # Example
1240/// The scenario is we want to get combination from single source of data
1241/// then distribute the combination to two workers which read each combination
1242/// then do something about it, which in this example, simply print it.
1243///
1244/// ```
1245/// use permutator::combination_cell;
1246/// use std::fmt::Debug;
1247/// use std::rc::Rc;
1248/// use std::cell::RefCell;
1249///
1250/// // define a trait that represent a data consumer
1251/// trait Consumer {
1252/// fn consume(&self); // cannot mut data because rule of no more than 1 ref mut at a time.
1253/// }
1254///
1255/// struct Worker1<'a, T : 'a> {
1256/// data : Rc<RefCell<&'a mut[&'a T]>> // A reference to each combination
1257/// }
1258///
1259/// impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
1260/// fn consume(&self) {
1261/// // Read data then do something about it. In this case, simply print it.
1262/// println!("Work1 has {:?}", self.data.borrow());
1263/// }
1264/// }
1265///
1266/// struct Worker2<'a, T : 'a> {
1267/// data : Rc<RefCell<&'a mut[&'a T]>> // A reference to each combination
1268/// }
1269///
1270/// impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
1271/// fn consume(&self) {
1272/// // Read data then do something about it. In this case, simply print it.
1273/// println!("Work2 has {:?}", self.data.borrow());
1274/// }
1275/// }
1276///
1277/// fn start_combination_process<'a>(data : &'a[i32], cur_result : Rc<RefCell<&'a mut[&'a i32]>>, k : usize, consumers : Vec<Box<Consumer + 'a>>) {
1278/// combination_cell(data, k, cur_result, || {
1279/// consumers.iter().for_each(|c| {
1280/// c.consume();
1281/// })
1282/// });
1283/// }
1284/// let k = 3;
1285/// let data = &[1, 2, 3, 4, 5];
1286/// let mut result = vec![&data[0]; k];
1287///
1288/// let shared = Rc::new(RefCell::new(result.as_mut_slice()));
1289/// let worker1 = Worker1 {
1290/// data : Rc::clone(&shared)
1291/// };
1292/// let worker2 = Worker2 {
1293/// data : Rc::clone(&shared)
1294/// };
1295/// let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
1296/// start_combination_process(data, shared, k, consumers);
1297/// ```
1298/// # See
1299/// - [combination function](fn.combination.html)
1300pub fn combination_cell<'a, T>(domain: &'a[T], r : usize, result : Rc<RefCell<&'a mut [&'a T]>>, mut cb : impl FnMut() -> ()) {
1301 let mut mask = 0u128;
1302 create_k_set_in_cell(domain, r, &result, &mut mask);
1303 cb();
1304
1305 while let Some(_) = swap_k_in_cell((&result, &mut mask), domain) {
1306 cb();
1307 }
1308}
1309
1310/// # Deprecated
1311/// See [combination function](fn.combination.html) for reason of
1312/// deprecation
1313///
1314/// Similar to [combination function](fn.combination.html) except
1315/// the way it return the combination.
1316/// It return result through Rc<RefCell<>> to mutable slice of result.
1317/// It'll notify caller on each new result via empty callback function.
1318/// # Parameters
1319/// - `domain` A raw data to get combination.
1320/// - `r` A size of each combination.
1321/// - `result` An Rc<RefCell<>> to mutable slice of length equals to `r`
1322/// - `cb` A callback function which will be called after new combination
1323/// in `result` is set.
1324/// # Return
1325/// This function return result through function's parameter `result` and
1326/// notify caller that new result is available through `cb` callback function.
1327/// # Rationale
1328/// The [combination function](fn.combination.html) return value in
1329/// callback parameter. It limit the lifetime of return combination to be
1330/// valid only inside it callback. To use it on different thread, it
1331/// need to copy the value which will have performance penalty.
1332/// This function provide alternative way to share data between thread.
1333/// It will write new result into Arc<RwLock<>> of Vec owned inside RwLock.
1334/// Since it write data directly into Vec, other threads won't know that
1335/// new data is wrote. The combination generator thread need to notify
1336/// other threads via channel. This introduce another problem.
1337/// Since combination generator write data directly into shared memory address,
1338/// it need to know if all other threads are done using the data.
1339/// Otherwise, in worst case, combination generator thread may dominate all other
1340/// threads and hold write lock until it done generate every value.
1341/// To solve such issue, combination generator thread need to get notified
1342/// when each thread has done using the data.
1343/// # Example
1344/// The scenario is we want to get combination from single source of data
1345/// then distribute the combination to two workers which read each combination
1346/// then do something about it, which in this example, simply print it.
1347///
1348/// ```
1349/// use permutator::combination_sync;
1350/// use std::fmt::Debug;
1351/// use std::sync::{Arc, RwLock};
1352/// use std::sync::mpsc;
1353/// use std::sync::mpsc::{Receiver, SyncSender};
1354/// use std::thread;
1355///
1356/// fn start_combination_process<'a>(data : &'a[i32], cur_result : Arc<RwLock<Vec<&'a i32>>>, k : usize, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
1357/// use std::time::Instant;
1358/// let timer = Instant::now();
1359/// let mut counter = 0;
1360/// combination_sync(data, k, cur_result, || {
1361/// notifier.iter().for_each(|n| {
1362/// n.send(Some(())).unwrap(); // notify every thread that new data available
1363/// });
1364///
1365/// for _ in 0..notifier.len() {
1366/// release_recv.recv().unwrap(); // block until all thread reading data notify on read completion
1367/// }
1368///
1369/// counter += 1;
1370/// });
1371///
1372/// notifier.iter().for_each(|n| {n.send(None).unwrap()}); // notify every thread that there'll be no more data.
1373///
1374/// println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
1375/// }
1376/// let k = 3;
1377/// let data = &[1, 2, 3, 4, 5];
1378/// let result = vec![&data[0]; k];
1379/// let result_sync = Arc::new(RwLock::new(result));
1380///
1381/// // workter thread 1
1382/// let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
1383/// let (main_send, main_recv) = mpsc::sync_channel(0);
1384/// let t1_local = main_send.clone();
1385/// let t1_dat = Arc::clone(&result_sync);
1386/// thread::spawn(move || {
1387/// while let Some(_) = t1_recv.recv().unwrap() {
1388/// let result : &Vec<&i32> = &*t1_dat.read().unwrap();
1389/// println!("Thread1: {:?}", result);
1390/// t1_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
1391/// }
1392/// println!("Thread1 is done");
1393/// });
1394///
1395/// // worker thread 2
1396/// let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
1397/// let t2_dat = Arc::clone(&result_sync);
1398/// let t2_local = main_send.clone();
1399/// thread::spawn(move || {
1400/// while let Some(_) = t2_recv.recv().unwrap() {
1401/// let result : &Vec<&i32> = &*t2_dat.read().unwrap();
1402/// println!("Thread2: {:?}", result);
1403/// t2_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
1404/// }
1405/// println!("Thread2 is done");
1406/// });
1407///
1408/// // main thread that generate result
1409/// thread::spawn(move || {
1410/// start_combination_process(data, result_sync, k, vec![t1_send, t2_send], main_recv);
1411/// }).join().unwrap();
1412/// ```
1413/// # See
1414/// - [combination function](fn.combination.html)
1415pub fn combination_sync<'a, T>(domain: &'a[T], r : usize, result : Arc<RwLock<Vec<&'a T>>>, mut cb : impl FnMut() -> ()) {
1416 let mut mask = 0u128;
1417 create_k_set_sync(domain, r, &result, &mut mask);
1418 cb();
1419
1420 while let Some(_) = swap_k_sync((&result, &mut mask), domain) {
1421 cb();
1422 }
1423}
1424
1425/// A core logic that generate a combination
1426///
1427/// # Parameters
1428/// 1. slice of T - Source of combination
1429/// 2. usize - size of combination.
1430/// 3. closure - function to generate a first result.
1431/// It tooks ref mut of cursor, ref of domain, and the size of combination.
1432/// It return object to store result.
1433/// 4. closure - function that set each element of result to some value.
1434/// It tooks index of result, an index of domain, and a ref mut object to store result
1435/// 5. closure - function that got call on each new combination.
1436///
1437/// # Panic
1438/// It panic when size of combination is larger that length of source.
1439fn _core_large_combination<'a, T : 'a, R : 'a>(
1440 // source of combination
1441 domain : &'a [T],
1442 // combination size
1443 r : usize,
1444 // A closure that took ref mut of cursor, ref of domain, and the size of combination. It return object to store result
1445 // It take ownership of result from environment and move it into this function.
1446 first_result_fn : impl FnOnce(&mut Vec<usize>, &'a [T], usize) -> R,
1447 // A closure that took index of result, an index of domain, and object to store result
1448 mut next_result_fn : impl FnMut(usize, usize, &mut R),
1449 // A callback function that get once on each new combination.
1450 // The new combination is sent as ref as function paramter.
1451 mut cb : impl FnMut(&R))
1452{
1453 /// Move cursor and update result
1454 #[inline(always)]
1455 fn move_cur_res<'a, T, R>(c : &mut [usize], domain : &'a [T], result : &mut R, next_result_fn : &mut dyn FnMut(usize, usize, &mut R)) {
1456 let n = c.len();
1457 let max = domain.len();
1458 let mut i = c.len() - 1;
1459
1460 if c[i] < max - n + i {
1461 c[i] += 1;
1462 next_result_fn(i, c[i], result);
1463 } else {
1464 // find where to start reset cursor
1465 while c[i] >= max - n + i {
1466 i -= 1;
1467 }
1468
1469 c[i] += 1;
1470 next_result_fn(i, c[i], result);
1471 i += 1;
1472 // reset all cursor from `i + 1`
1473 (i..c.len()).for_each(|i| {
1474 c[i] = c[i - 1] + 1;
1475 next_result_fn(i, c[i], result);
1476 });
1477 }
1478 }
1479
1480 assert_ne!(r, 0, "The combination size cannot be 0");
1481 assert!(domain.len() >= r, "The combination size cannot be larger than size of data");
1482
1483 let mut c : Vec<usize> = Vec::new();
1484 let mut result = first_result_fn(&mut c, domain, r);
1485 cb(&result);
1486 let n = r - 1;
1487 c[n] += 1;
1488
1489 if c[n] < domain.len() {
1490 next_result_fn(n, c[n], &mut result);
1491 cb(&result);
1492 } else {
1493 return;
1494 }
1495
1496 while c[0] < domain.len() - r {
1497
1498 // move cursor and update result
1499 move_cur_res(&mut c, domain, &mut result, &mut next_result_fn);
1500 cb(&result);
1501 }
1502}
1503
1504/// Generate a r-combination from given domain and call callback function
1505/// on each combination.
1506///
1507/// # Parameter
1508/// 1. `domain : &[T]` - A slice contain a domain to generate r-combination
1509/// 2. `r : usize` - A size of combination
1510/// 3. `cb : FnMut(&[&T])` - A callback that return each combination
1511///
1512/// # Panic
1513/// It panic when `r` > `domain.len()`
1514pub fn large_combination<'a, T, F>(domain: &'a [T], r : usize, mut cb : F)
1515 where T : 'a,
1516 for<'r> F : FnMut(&'r[&'a T]) + 'a
1517{
1518 let mut result : Vec<&T> = Vec::with_capacity(r);
1519 _core_large_combination(domain,
1520 r,
1521 #[inline(always)]
1522 |c, domain, r| {
1523 (0..r).for_each(|i| {
1524 result.push(&domain[i]);
1525 c.push(i);
1526 });
1527
1528 result
1529 },
1530 #[inline(always)]
1531 |i, j, result| {
1532 result[i] = &domain[j];
1533 },
1534 #[inline(always)]
1535 |result| {
1536 cb(result);
1537 }
1538 );
1539}
1540
1541/// Generate a r-combination from given domain and call callback function
1542/// on each combination. The result will be return into ref mut pointer.
1543///
1544/// # Parameter
1545/// 1. `domain : &[T]` - A slice contain a domain to generate r-combination
1546/// 2. `r : usize` - A size of combination
1547/// 3. `result : *mut [&T]` - A mutable pointer to store result
1548/// 4. `cb : FnMut()` - A callback that notify caller on each combination
1549///
1550/// # Panic
1551/// - It panic when `r > domain.len()` or `r > result.len()`
1552///
1553/// # Rationale
1554/// This function took *mut [&T] to store result. It allow caller to easily share
1555/// result outside callback function without copying/cloning each result.
1556/// It sacrifice safety for performance.
1557///
1558/// # Safety
1559/// - It doesn't check whether the pointer is valid or not.
1560/// - It doesn't free memory occupied by result.
1561/// - It may cause data race
1562/// - Mutating `result` may cause undesired behavior.
1563/// - Storing `result` will get overwritten when new combination is return.
1564/// - All other unsafe Rust condition may applied.
1565pub unsafe fn unsafe_large_combination<'a, T : 'a>(domain: &'a [T], r : usize, result : *mut [&'a T], mut cb : impl FnMut()) {
1566 _core_large_combination(domain,
1567 r,
1568 #[inline(always)]
1569 |c, domain, r| {
1570 let result = &mut *result;
1571 (0..r).for_each(|i| {
1572 result[i] = &domain[i];
1573 c.push(i);
1574 });
1575
1576 result
1577 },
1578 #[inline(always)]
1579 |i, j, result| {
1580 result[i] = &domain[j];
1581 },
1582 #[inline(always)]
1583 |_| {
1584 cb();
1585 }
1586 );
1587}
1588
1589/// Generate a r-combination from given domain and call callback function
1590/// on each combination. The result will be return into Rc<RefCell<>>.
1591///
1592/// # Parameter
1593/// 1. `domain : &[T]` - A slice contain a domain to generate r-combination
1594/// 2. `r : usize` - A size of combination
1595/// 3. 'result : Rc<RefCell<&mut [&T]>>` - A result container object.
1596/// 4. `cb : FnMut()` - A callback that notify caller on each combination
1597///
1598/// # Panic
1599/// It panic when `r > domain.len()` or `r > result.borrow().len()`
1600///
1601/// # Rationale
1602/// It allow easily safe sharing of result to some degree with minor
1603/// performance overhead and some some usage constraint.
1604/// - `result` will get overwritten on each new combination.
1605/// - Storing `result` will get overwritten when new combination is return.
1606pub fn large_combination_cell<'a, T : 'a>(domain: &'a[T], r : usize, result : Rc<RefCell<&'a mut [&'a T]>>, mut cb : impl FnMut() -> ()) {
1607 _core_large_combination(domain,
1608 r,
1609 #[inline(always)]
1610 |c, domain, r| {
1611 (0..r).for_each(|i| {
1612 result.borrow_mut()[i] = &domain[i];
1613 c.push(i);
1614 });
1615
1616 result
1617 },
1618 #[inline(always)]
1619 |i, j, result| {
1620 result.borrow_mut()[i] = &domain[j];
1621 },
1622 #[inline(always)]
1623 |_| {
1624 cb();
1625 }
1626 );
1627}
1628
1629/// Generate a r-combination from given domain and call callback function
1630/// on each combination. The result will be return into Arc<RwLock<>>.
1631///
1632/// # Parameter
1633/// 1. `domain : &[T]` - A slice contain a domain to generate r-combination
1634/// 2. `r : usize` - A size of combination
1635/// 3. 'result : Arc<RwLock<Vec<&T>>>` - A result container object.
1636/// 4. `cb : FnMut()` - A callback that notify caller on each combination
1637///
1638/// # Panic
1639/// It panic when `r > domain.len()` or `r > result.read().unwrap().len()`
1640///
1641/// # Rationale
1642/// It allow easily safe sharing of result with other thread to some degree
1643/// with minor performance overhead and some some usage constraint.
1644/// - `result` will get overwritten on each new combination.
1645/// - Storing `result` will get overwritten when new combination is return.
1646pub fn large_combination_sync<'a, T : 'a>(domain: &'a[T], r : usize, result : Arc<RwLock<Vec<&'a T>>>, mut cb : impl FnMut() -> ()) {
1647 _core_large_combination(domain,
1648 r,
1649 #[inline(always)]
1650 |c, domain, r| {
1651 {
1652 let mut writer = result.write().unwrap();
1653 (0..r).for_each(|i| {
1654 writer[i] = &domain[i];
1655 c.push(i);
1656 });
1657 }
1658
1659 result
1660 },
1661 #[inline(always)]
1662 |i, j, result| {
1663 result.write().unwrap()[i] = &domain[j];
1664 },
1665 #[inline(always)]
1666 |_| {
1667 cb();
1668 }
1669 );
1670}
1671
1672/// A core heap permutation algorithm.
1673/// # Parameters
1674/// - `n` size of entire data
1675/// - `swap` a closure to swap the data
1676/// - `cb` a callback function that get call on each permutation
1677/// # Closure execution sequence
1678/// 1. `swap` once
1679/// 2. `cb` once
1680/// 3. go to step 1 until permutation is `n` times
1681fn _heap_permutation_core(n : usize, mut swap : impl FnMut(usize, usize), mut cb : impl FnMut()) {
1682 let mut c = vec![0; n];
1683 let mut i = 0;
1684 while i < n {
1685 if c[i] < i {
1686 if i & 1 == 0 { // equals to mod 2 because it take only 0 and 1 aka last bit
1687 swap(0, i);
1688 } else {
1689 swap(c[i], i);
1690 }
1691
1692 cb();
1693 c[i] += 1;
1694 i = 0;
1695 } else {
1696 c[i] = 0;
1697 i += 1;
1698 }
1699 }
1700}
1701
1702/// Heap permutation which permutate variable `d` in place and call `cb` function
1703/// for each permutation done on `d`.
1704///
1705/// # Parameter
1706/// - `d` a data to be permuted.
1707/// - `cb` a callback function that will be called several times for each permuted value.
1708///
1709/// # Example
1710/// ```
1711/// use permutator::heap_permutation;
1712/// heap_permutation(&mut [1, 2, 3], |p| {
1713/// // call multiple times. It'll print [1, 2, 3], [2, 1, 3], [3, 1, 2],
1714/// // [1, 3, 2], [2, 3, 1], and [3, 2, 1] respectively.
1715/// println!("{:?}", p);
1716/// });
1717/// ```
1718/// # See
1719/// - [k_permutation_sync](fn.k_permutation_sync.html) for example of
1720/// how to implement multi-thread data sync
1721/// - The [HeapPermutationIterator struct](struct.HeapPermutationIterator.html)
1722/// provide alternate way of getting permutation but in iterative way.
1723/// # Warning
1724/// The permutation is done in place which mean the parameter `d` will be
1725/// mutated.
1726///
1727/// # Notes
1728/// 1. The value passed to callback function will equals to value inside parameter `d`.
1729///
1730/// # Breaking change from 0.3.x to 0.4
1731/// Since version 0.4.0, the first result return by this iterator
1732/// will be the original value
1733pub fn heap_permutation<'a, T>(d : &'a mut [T], mut cb : impl FnMut(&[T]) -> () + 'a) {
1734 let copied = d as *const [T];
1735 unsafe {
1736 cb(&*copied);
1737 // It'd safe because the mutation on `d` will be done
1738 // before calling `cb` closure and until `cb` closure is return
1739 // the mutation closure won't get call.
1740 _heap_permutation_core(
1741 d.len(),
1742 #[inline(always)] |from, to| {
1743 d.swap(from, to);
1744 },
1745 #[inline(always)] || {
1746 cb(&*copied)
1747 });
1748 }
1749}
1750
1751/// Heap permutation which permutate variable `d` in place and call `cb` function
1752/// for each permutation done on `d`.
1753///
1754/// # Parameter
1755/// - `d` an Rc<RefCell<>> to mutable slice data to be permuted.
1756/// - `cb` a callback function that will be called several times for each permuted value.
1757///
1758/// # Example
1759/// ```
1760/// use permutator::heap_permutation_cell;
1761/// use std::rc::Rc;
1762/// use std::cell::RefCell;
1763/// let data : &mut[i32] = &mut [1, 2, 3];
1764/// let sharable = Rc::new(RefCell::new(data));
1765/// heap_permutation_cell(&sharable, || {
1766/// // call other functions/objects that use `sharable` variable.
1767/// });
1768/// ```
1769///
1770/// # Warning
1771/// The permutation is done in place which mean the parameter `d` will be
1772/// mutated.
1773///
1774/// # Notes
1775/// 1. The value passed to callback function will equals to value inside parameter `d`.
1776///
1777/// # Breaking change from 0.3.x to 0.4
1778/// Since version 0.4.0, the first result return by this iterator
1779/// will be the original value
1780pub fn heap_permutation_cell<T>(d : &Rc<RefCell<&mut [T]>>, mut cb : impl FnMut() -> ()) {
1781 cb();
1782
1783 // need borrow expr outside function call because if the expr is
1784 // put inline within the function call, Rust runtime hold borrowed `d`
1785 // for an entire function call
1786 let n = d.borrow().len();
1787 _heap_permutation_core(
1788 n,
1789 #[inline(always)] |from, to| {
1790 d.borrow_mut().swap(from, to);
1791 },
1792 cb
1793 );
1794}
1795
1796/// Heap permutation which permutate variable `d` in place and call `cb` function
1797/// for each permutation done on `d`.
1798///
1799/// # Parameter
1800/// - `d` an Rc<RefCell<>> to mutable slice data to be permuted.
1801/// - `cb` a callback function that will be called several times for each permuted value.
1802///
1803/// # Warning
1804/// The permutation is done in place which mean the parameter `d` will be
1805/// mutated.
1806///
1807/// # Notes
1808/// 1. The value passed to callback function will equals to value inside parameter `d`.
1809///
1810/// # Breaking change from 0.3.x to 0.4
1811/// Since version 0.4.0, the first result return by this iterator
1812/// will be the original value
1813pub fn heap_permutation_sync<T>(d : &Arc<RwLock<Vec<T>>>, mut cb : impl FnMut() -> ()) {
1814 cb();
1815
1816 // need read lock expr outside function call because if the expr is
1817 // put inline within the function call, Rust runtime obtain the lock
1818 // for an entire function call
1819 let n = d.read().unwrap().len();
1820 _heap_permutation_core(
1821 n,
1822 #[inline(always)] |from, to| {
1823 d.write().unwrap().swap(from, to);
1824 },
1825 cb
1826 );
1827}
1828
1829/// A macro that perform core logic of k-permutation.
1830///
1831/// # Parameters
1832/// 1. `k` - The size of each permutation.
1833/// 2. `n` - The total length of data
1834/// 3. `swap_fn` - The closure that perform data swap
1835/// 4. `cb` - The callback function that will return each permutation.
1836#[allow(unused)]
1837macro_rules! _k_permutation_core {
1838 ($k : expr, $n : expr, $swap_fn : expr, $permute_fn : expr, $cb : expr) => {
1839 if $n < $k {
1840 panic!("Cannot create k-permutation of size {} for data of length {}", $k, $n);
1841 } else if $k == 0 {
1842 // k = 0 mean mean permutation frame size is 0, it cannot have permutation
1843 return
1844 }
1845
1846 $cb;
1847 $permute_fn; // generate all possible permutation for initial subset
1848
1849 while let Some(_) = $swap_fn { // repeatly swap element
1850 $cb;
1851 $permute_fn; // generate all possible permutation per each subset
1852 }
1853 };
1854}
1855
1856
1857/// Generate k-permutation over slice of `d`. For example: d = &[1, 2, 3]; k = 2.
1858/// The result will be [1, 2], [2, 1], [1, 3], [3, 1], [2, 3], [3, 2]
1859///
1860/// The implementation calculate each combination by [large_combination function](fn.large_combination.html)
1861/// then apply Heap's algorithm. There's [KPermutationIterator struct](struct.KPermutationIterator.html)
1862/// that also generate KPermutationIterator but in iterative style.
1863/// The performance of this function is slightly faster than
1864/// [KPermutationIterator struct](struct.KPermutationIterator.html) by about 15%-20%
1865/// tested in uncontrol environment.
1866///
1867/// # Examples
1868/// The example below will generate 4-permutation over 6 data items.
1869/// The first combination will be used to generate all permutation first.
1870/// So the first three result will be [1, 2, 3, 4], [2, 1, 3, 4], [3, 1, 2, 4]
1871/// as per Heap permutation algorithm.
1872/// After all permutation for [1, 2, 3, 4] is calculated, it'll use Gospel
1873/// algorithm to find next combination which is [1, 2, 3, 5] then
1874/// permutate it until every permutation is done.
1875/// It'll keep repeating above process until last combination, which is
1876/// [3, 4, 5, 6], is completely permuted then the function will return.
1877///
1878/// ```
1879/// use permutator::k_permutation;
1880/// use std::time::{Instant};
1881///
1882/// let data = [1, 2, 3, 4, 5, 6];
1883/// let mut counter = 0;
1884/// let timer = Instant::now();
1885///
1886/// k_permutation(&data, 4, |permuted| {
1887/// // uncomment line below to print all k-permutation
1888/// // println!("{}:{:?}", counter, permuted);
1889/// counter += 1;
1890/// });
1891/// println!("Done {} permuted in {:?}", counter, timer.elapsed());
1892/// ```
1893/// # Panic
1894/// This function panic when `k == 0` or `k > d.len()`
1895///
1896/// # Notes
1897/// 1. This function doesn't support jumping into specific nth permutation because
1898/// the permutation is out of lexicographic order per Heap's algorithm limitation.
1899/// For jumping into specific position, it require lexicographic ordered permutation.
1900/// 2. This function take callback function to speed up permutation processing.
1901/// It will call the callback right in the middle of Heap's loop then continue
1902/// the loop.
1903/// 3. This function use single thread.
1904///
1905/// # See
1906/// - [Heap's algorithm in Wikipedia page, October 9, 2018](https://en.wikipedia.org/wiki/Heap%27s_algorithm)
1907pub fn k_permutation<'a, T, F>(d : &'a [T], k : usize, mut cb : F)
1908 where T : 'a,
1909 for<'r> F : FnMut(&'r [&'a T]) + 'a
1910{
1911 assert_ne!(k, 0);
1912 assert!(k <= d.len());
1913
1914 large_combination(d, k, move |result| {
1915 heap_permutation(&mut result.to_owned(), |r| cb(r));
1916 });
1917}
1918
1919/// Similar to safe [k_permutation function](fn.k_permutation.html) except
1920/// the way it return the permutation.
1921/// It return result through mutable pointer to result assuming the
1922/// pointer is valid. It'll notify caller on each new result via empty
1923/// callback function.
1924/// # Parameters
1925/// - `d` A raw data to get k-permutation.
1926/// - `k` A size of each permutation.
1927/// - `result` A mutable pointer to slice of length equals to `k`
1928/// - `cb` A callback function which will be called after new combination
1929/// in `result` is set.
1930/// # Return
1931/// This function return result through function's parameter `result` and
1932/// notify caller that new result is available through `cb` callback function.
1933/// # Unsafe
1934/// This function is unsafe because it may dereference a dangling pointer,
1935/// may cause data race if multiple threads read/write to the same memory,
1936/// and all of those unsafe Rust condition will be applied here.
1937/// # Rationale
1938/// The safe [k_permutation function](fn.k_permutation.html) return value in
1939/// callback parameter. It limit the lifetime of return combination to be
1940/// valid only inside it callback. To use it outside callback scope, it
1941/// need to copy the value which will have performance penalty. Therefore,
1942/// jeopardize it own goal of being fast. This function provide alternative
1943/// way that sacrifice safety for performance.
1944///
1945/// # Example
1946/// The scenario is we want to get k-permutation from single source of data
1947/// then distribute the permutation to two workers which read each permutation
1948/// then do something about it, which in this example, simply print it.
1949///
1950/// ```
1951/// use permutator::unsafe_k_permutation;
1952/// use std::fmt::Debug;
1953/// // define a trait that represent a data consumer
1954/// trait Consumer {
1955/// fn consume(&self); // cannot mut data because rule of no more than 1 ref mut at a time.
1956/// }
1957///
1958/// struct Worker1<'a, T : 'a> {
1959/// data : &'a[&'a T] // A reference to each k-permutation
1960/// }
1961///
1962/// impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
1963/// fn consume(&self) {
1964/// // Read data then do something about it. In this case, simply print it.
1965/// println!("Work1 has {:?}", self.data);
1966/// }
1967/// }
1968///
1969/// struct Worker2<'a, T : 'a> {
1970/// data : &'a[&'a T] // A reference to each k-permutation
1971/// }
1972///
1973/// impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
1974/// fn consume(&self) {
1975/// // Read data then do something about it. In this case, simply print it.
1976/// println!("Work2 has {:?}", self.data);
1977/// }
1978/// }
1979///
1980/// unsafe fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : *mut [&'a i32], k : usize, consumers : Vec<Box<Consumer + 'a>>) {
1981/// unsafe_k_permutation(data, k, cur_result, || {
1982/// consumers.iter().for_each(|c| {
1983/// c.consume();
1984/// })
1985/// });
1986/// }
1987/// let k = 3;
1988/// let data = &[1, 2, 3, 4, 5];
1989/// let mut result = vec![&data[0]; k];
1990///
1991/// unsafe {
1992///
1993/// let shared = result.as_mut_slice() as *mut [&i32];
1994/// let worker1 = Worker1 {
1995/// data : &result
1996/// };
1997/// let worker2 = Worker2 {
1998/// data : &result
1999/// };
2000/// let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
2001/// start_k_permutation_process(data, shared, k, consumers);
2002/// }
2003/// ```
2004/// # Note
2005/// Performancewise, k_permutation is faster than unsafe_k_permutation.
2006/// The unsafe function is only faster when caller need to clone the result.
2007/// # See
2008/// - [k_permutation function](fn.k_permutation.html)
2009pub unsafe fn unsafe_k_permutation<'a, T>(d : &'a [T], k : usize, result : *mut [&'a T], mut cb : impl FnMut() -> ()) {
2010 assert_eq!(k, (*result).len());
2011
2012 unsafe_large_combination(d, k, result, || {
2013 // save combination
2014 let buffer = (*result).to_owned();
2015
2016 // permute the combination in place
2017 heap_permutation(&mut *result, |_| {
2018 cb();
2019 });
2020
2021 // restore combination so next combination is properly produce
2022 buffer.iter().enumerate().for_each(|(i, t)| (*result)[i] = *t)
2023 });
2024}
2025
2026/// Similar to safe [k_permutation function](fn.k_permutation.html) except
2027/// the way it return the permutation.
2028/// It return result through mutable pointer to result assuming the
2029/// pointer is valid. It'll notify caller on each new result via empty
2030/// callback function.
2031/// # Parameters
2032/// - `d` A raw data to get k-permutation.
2033/// - `k` A size of each permutation.
2034/// - `result` A mutable pointer to slice of length equals to `k`
2035/// - `cb` A callback function which will be called after new combination
2036/// in `result` is set.
2037/// # Return
2038/// This function return result through function's parameter `result` and
2039/// notify caller that new result is available through `cb` callback function.
2040/// # Rationale
2041/// The safe [k_permutation function](fn.k_permutation.html) return value in
2042/// callback parameter. It limit the lifetime of return combination to be
2043/// valid only inside it callback. To use it outside callback scope, it
2044/// need to copy the value which will have performance penalty. Therefore,
2045/// jeopardize it own goal of being fast. This function provide alternative
2046/// safe way to share the permutation with some minor performance cost.
2047/// This function is about 50% slower than the unsafe counterpart.
2048/// It's throughput is slightly slower than using a
2049/// [next_into_cell](struct.KPermutationIterator.html#method.next_into_cell) by
2050/// 15%-20% in uncontrol test environment.
2051///
2052/// # Example
2053/// The scenario is we want to get k-permutation from single source of data
2054/// then distribute the combination to two workers which read each permutation
2055/// then do something about it, which in this example, simply print it.
2056///
2057/// ```
2058/// use permutator::k_permutation_cell;
2059/// use std::fmt::Debug;
2060/// use std::rc::Rc;
2061/// use std::cell::RefCell;
2062///
2063/// trait Consumer {
2064/// fn consume(&self);
2065/// }
2066/// struct Worker1<'a, T : 'a> {
2067/// data : Rc<RefCell<&'a mut[&'a T]>>
2068/// }
2069/// impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
2070/// fn consume(&self) {
2071/// println!("Work1 has {:?}", self.data.borrow());
2072/// }
2073/// }
2074/// struct Worker2<'a, T : 'a> {
2075/// data : Rc<RefCell<&'a mut[&'a T]>>
2076/// }
2077/// impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
2078/// fn consume(&self) {
2079/// println!("Work2 has {:?}", self.data.borrow());
2080/// }
2081/// }
2082///
2083/// fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : Rc<RefCell<&'a mut [&'a i32]>>, k : usize, consumers : Vec<Box<Consumer + 'a>>) {
2084/// k_permutation_cell(data, k, cur_result, || {
2085/// consumers.iter().for_each(|c| {
2086/// c.consume();
2087/// })
2088/// });
2089/// }
2090/// let k = 3;
2091/// let data = &[1, 2, 3, 4, 5];
2092/// let mut result = vec![&data[0]; k];
2093/// let shared = Rc::new(RefCell::new(result.as_mut_slice()));
2094///
2095/// let worker1 = Worker1 {
2096/// data : Rc::clone(&shared)
2097/// };
2098/// let worker2 = Worker2 {
2099/// data : Rc::clone(&shared)
2100/// };
2101/// let consumers : Vec<Box<Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
2102/// start_k_permutation_process(data, shared, k, consumers);
2103/// ```
2104/// # Panic
2105/// Panic if `k == 0` or `k > d.len()`
2106///
2107/// # See
2108/// - [k_permutation function](fn.k_permutation.html)
2109pub fn k_permutation_cell<'a, T>(d : &'a [T], k : usize, result : Rc<RefCell<&'a mut [&'a T]>>, mut cb : impl FnMut() -> ()) {
2110 assert_ne!(k, 0);
2111 assert_eq!(k, result.borrow().len());
2112 large_combination_cell(d, k, Rc::clone(&result), || {
2113 // save combination
2114 let origin = (*result).borrow().to_owned();
2115
2116 // permute the combination in place
2117 heap_permutation_cell(&result, || {
2118 cb();
2119 });
2120
2121 // restore combination so next combination is properly produce
2122 origin.iter().enumerate().for_each(|(i, t)| result.borrow_mut()[i] = *t)
2123 });
2124}
2125
2126/// Similar to safe [k_permutation function](fn.k_permutation.html) except
2127/// the way it return the permutation.
2128/// It return result through mutable pointer to result assuming the
2129/// pointer is valid. It'll notify caller on each new result via empty
2130/// callback function.
2131/// # Parameters
2132/// - `d` A raw data to get k-permutation.
2133/// - `k` A size of each permutation.
2134/// - `result` A mutable pointer to slice of length equals to `k`
2135/// - `cb` A callback function which will be called after new combination
2136/// in `result` is set.
2137/// # Return
2138/// This function return result through function's parameter `result` and
2139/// notify caller that new result is available through `cb` callback function.
2140/// # Rationale
2141/// The [k_permutation function](fn.k_permutation.html) return value in
2142/// callback parameter. It limit the lifetime of return combination to be
2143/// valid only inside it callback. To use it outside callback scope, it
2144/// need to copy the value which will have performance penalty. Therefore,
2145/// jeopardize it own goal of being fast.
2146/// This function provide alternative way to share data between thread.
2147/// It will write new result into Arc<RwLock<>> of Vec owned inside RwLock.
2148/// Since it write data directly into Vec, other threads won't know that
2149/// new data is wrote. The combination generator thread need to notify
2150/// other threads via channel. This introduce another problem.
2151/// Since combination generator write data directly into shared memory address,
2152/// it need to know if all other threads are done using the data.
2153/// Otherwise, in worst case, combination generator thread may dominate all other
2154/// threads and hold write lock until it done generate every value.
2155/// To solve such issue, combination generator thread need to get notified
2156/// when each thread has done using the data.
2157///
2158/// # Example
2159/// The scenario is we want to get k-permutation from single source of data
2160/// then distribute the combination to two workers which read each permutation
2161/// then do something about it, which in this example, simply print it.
2162///
2163/// ```
2164/// use permutator::k_permutation_sync;
2165/// use std::sync::{Arc, RwLock};
2166/// use std::sync::mpsc;
2167/// use std::sync::mpsc::{SyncSender, Receiver};
2168/// use std::thread;
2169///
2170/// fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : Arc<RwLock<Vec<&'a i32>>>, k : usize, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
2171/// use std::time::Instant;
2172/// let timer = Instant::now();
2173/// let mut counter = 0;
2174/// k_permutation_sync(data, k, cur_result, || {
2175/// notifier.iter().for_each(|n| {
2176/// n.send(Some(())).unwrap(); // notify every thread that new data available
2177/// });
2178///
2179/// for _ in 0..notifier.len() {
2180/// release_recv.recv().unwrap(); // block until all thread reading data notify on read completion
2181/// }
2182///
2183/// counter += 1;
2184/// });
2185///
2186/// notifier.iter().for_each(|n| {n.send(None).unwrap()}); // notify every thread that there'll be no more data.
2187///
2188/// println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
2189/// }
2190/// let k = 3;
2191/// let data = &[1, 2, 3, 4, 5];
2192/// let result = vec![&data[0]; k];
2193/// let result_sync = Arc::new(RwLock::new(result));
2194///
2195/// // workter thread 1
2196/// let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
2197/// let (main_send, main_recv) = mpsc::sync_channel(0);
2198/// let t1_local = main_send.clone();
2199/// let t1_dat = Arc::clone(&result_sync);
2200/// thread::spawn(move || {
2201/// while let Some(_) = t1_recv.recv().unwrap() {
2202/// let result : &Vec<&i32> = &*t1_dat.read().unwrap();
2203/// println!("Thread1: {:?}", result);
2204/// t1_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
2205/// }
2206/// println!("Thread1 is done");
2207/// });
2208///
2209/// // worker thread 2
2210/// let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
2211/// let t2_dat = Arc::clone(&result_sync);
2212/// let t2_local = main_send.clone();
2213/// thread::spawn(move || {
2214/// while let Some(_) = t2_recv.recv().unwrap() {
2215/// let result : &Vec<&i32> = &*t2_dat.read().unwrap();
2216/// println!("Thread2: {:?}", result);
2217/// t2_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
2218/// }
2219/// println!("Thread2 is done");
2220/// });
2221///
2222/// // main thread that generate result
2223/// thread::spawn(move || {
2224/// start_k_permutation_process(data, result_sync, k, vec![t1_send, t2_send], main_recv);
2225/// }).join().unwrap();
2226/// ```
2227/// # See
2228/// - [k_permutation function](fn.k_permutation.html)
2229pub fn k_permutation_sync<'a, T>(d : &'a [T], k : usize, result : Arc<RwLock<Vec<&'a T>>>, mut cb : impl FnMut() -> ()) {
2230 assert_ne!(k, 0);
2231 assert_eq!(k, result.read().unwrap().len());
2232 large_combination_sync(d, k, Arc::clone(&result), || {
2233
2234 // save combination
2235 let origin = (*result).read().unwrap().to_owned();
2236
2237 // permute the combination in place
2238 heap_permutation_sync(&result, || {
2239 cb();
2240 });
2241
2242 // restore combination so next combination is properly produce
2243 origin.iter().enumerate().for_each(|(i, t)| result.write().unwrap()[i] = *t)
2244 });
2245}
2246
2247/// A lexicographic ordered permutation based on ["Algoritm X" published by
2248/// Donald E. Knuth.](http://www.cs.utsa.edu/~wagner/knuth/fasc2b.pdf) page 20.
2249/// The sample implementation in C++ can be found in [Kevin Lynch
2250/// repository.](https://gist.github.com/klynch/807973/cf05e785a68a5ae8b6a3381752583b97186f6140)
2251/// He implemented Algorithm X in an structured iterator style.
2252/// The discussion on how to implement "Algorithm X" in structured fashion in
2253/// discussed [here](https://stackoverflow.com/questions/37079307/untying-knuths-knots-how-to-restructure-spaghetti-code)
2254/// The implementation here is inspired by the post from stackoverflow.
2255///
2256/// # Parameters
2257/// - d : &[T] - a data to be permuted
2258/// - result_fn : FnMut(usize, usize) - Function/Closure that responsible for
2259/// assign a data into result container. The first parameter is an index of result
2260/// to be re-assigned. The second parameter is an index of data to be assigned to result.
2261/// - t : FnMut(usize) -> bool - a function defined by "Algorithm X" that get called
2262/// by current "prefix" to check if such "prefix" need to be kept. If true, the
2263/// "prefix" will be kept. If false, the entire sub-tree with this "prefix" will be skip.
2264/// The parameter will be usize which is max bound of current result. The "prefix"
2265/// therefore shall be a subslice of range 0 till given parameter. For example,
2266/// result[0..k]
2267/// - cb : FnMut() - Callback function that shall return result to caller
2268fn _x_permutation_core<T>(d : &[T], mut result_fn : impl FnMut(usize, usize), mut t : impl FnMut(usize) -> bool, mut cb : impl FnMut()) {
2269 /// Return tuple of (a, k, l, n) where
2270 /// - a is a Vec<usize>, array holding index of permuted.
2271 /// - k is usize and l is Vec<usize>
2272 /// Init value is k = 1
2273 /// - l is a Vec<usize>
2274 /// Init l[k] = k + 1 where 0 <= k < n
2275 /// l[n] = 0
2276 /// - n is usize, a length of data
2277 /// - perm is Vec<&T>, holding permuted value
2278 /// - u is Vec<usize>, holding undo vec
2279 #[inline(always)]
2280 fn init<T>(d : &[T]) -> (Vec<usize>, usize, Vec<usize>, usize, Vec<usize>) {
2281 // l[k] = k + 1 where 0 <= k < n
2282 let mut l : Vec<usize> = (0..d.len()).map(|k| k + 1).collect();
2283 let a : Vec<usize> = (0..=d.len()).map(|v| v).collect();
2284 let n = d.len();
2285 let u = vec![0; n + 1];
2286
2287 // l[n] = 0
2288 l.push(0);
2289 let k = 1;
2290
2291 (a, k, l, n, u)
2292 }
2293
2294 /// Return tuple of (p, q) where
2295 /// p = 0 and q = l[0]
2296 #[inline(always)]
2297 fn enter(l : &[usize]) -> (usize, usize) {
2298 return (0, l[0])
2299 }
2300
2301 // "Algo X" X1
2302 let (mut a, mut k, mut l, n, mut u) = init(d);
2303 // "Algo X" X2
2304 let (mut p, mut q) = enter(&l);
2305
2306 loop {
2307 // "Algo X" X3
2308 // perm[k - 1] = &d[q - 1];
2309 result_fn(k - 1, q - 1);
2310 a[k] = q;
2311
2312 if t(k) { // part of "Algo X" X3
2313 if k == n { // part of "Algo X" X3
2314 cb(); // visit part of "Algo X" X3
2315
2316 loop { // condition of "Algo X" X5
2317 // "Algo X" X6
2318 k -= 1;
2319
2320 if k == 0 {
2321 return;
2322 } else {
2323 p = u[k];
2324 q = a[k];
2325 l[p] = q;
2326
2327 // "Algo X" X5
2328 p = q;
2329 q = l[p];
2330
2331 if q != 0 {
2332 break;
2333 }
2334 }
2335 }
2336 } else {
2337 // "Algo X" X4
2338 u[k] = p;
2339 l[p] = l[q];
2340 k += 1;
2341
2342 // "Algo X" X2
2343 let (new_p, new_q) = enter(&l);
2344 p = new_p;
2345 q = new_q;
2346 }
2347 } else {
2348 // "Algo X" X5
2349 loop {
2350 p = q;
2351 q = l[p];
2352
2353 if q != 0 {
2354 break;
2355 }
2356
2357 // "Algo X" X6
2358 k -= 1;
2359
2360 if k == 0 {
2361 return;
2362 } else {
2363 p = u[k];
2364 q = a[k];
2365 l[p] = q;
2366 }
2367 }
2368 }
2369 }
2370}
2371
2372/// A lexicographic ordered permutation based on ["Algoritm X" published by
2373/// Donald E. Knuth.](http://www.cs.utsa.edu/~wagner/knuth/fasc2b.pdf) page 20.
2374///
2375/// If order is not important, consider using [heap permutation](fn.heap_permutation.html)
2376/// function instead. This function is 3 times slower than [heap
2377/// permutation](fn.heap_permutation.html) in uncontroll test environment.
2378///
2379/// The algorithm work by simulate tree traversal where some branch can be
2380/// skip altogether. This is archive by provided `t` function that take
2381/// slice of partial result as parameter. If the partial result needed to be skip,
2382/// return false. Otherwise, return true and the algorithm will call this function
2383/// again when the branch is descended deeper. For example: First call to `t` may
2384/// contain [1]. If `t` return true, it will be called again with [1, 2]. If it
2385/// return true, and there's leaf node, cb will be called with [1, 2]. On the other hand,
2386/// if `t` is called with [1, 3] and it return false, it won't call the callback.
2387/// If `t` is called with [4] and it return false, it won't try to traverse deeper even
2388/// if there're [4, 5], or [4, 6]. It will skip altogether and call `t` with [7].
2389/// The process goes on until every branch is traversed.
2390///
2391/// # Example
2392/// Get all lexicalgraphic ordered permutation
2393/// ```Rust
2394/// use permutator::x_permutation;
2395///
2396/// let data = vec![1, 2, 3, 4];
2397/// let mut counter = 0;
2398///
2399/// x_permutation(&data, |_| true, |p| {
2400/// println!("{:?}", p);
2401/// counter += 1;
2402/// });
2403///
2404/// assert_eq!(factorial(data.len()), counter);
2405/// ```
2406/// Skip all permutation that has `1` in first element.
2407/// ```Rust
2408/// use permutator::x_permutation;
2409///
2410/// let data : Vec<u8> = vec![1, 2, 3, 4];
2411/// let mut counter = 0;
2412///
2413/// x_permutation(&data, |f| {
2414/// *f[0] != 1u8 // filter all permutation that start with 1
2415/// }, |p| {
2416/// println!("{:?}", p);
2417/// counter += 1;
2418/// });
2419///
2420/// assert_eq!(factorial(data.len()) - factorial(data.len() - 1), counter);
2421/// ```
2422/// Multi-threads permutation example
2423/// ```Rust
2424/// use std::sync::{Arc, RwLock};
2425/// use permutator::{get_permutation_for, x_permutation};
2426///
2427/// let mut data : Vec<u8> = (0..5u8).map(|v| v).collect();
2428/// let threads = 2usize;
2429/// let chunk = data.len() / threads; // split data into 3 threads.
2430/// let complete_count = Arc::new(RwLock::new(0u64));
2431/// let total_counter = Arc::new(RwLock::new(0u64));
2432/// for i in 0..threads {
2433/// let u_bound = match i {
2434/// j if j == threads - 1 => data.len() as u8, // last thread do all the rest
2435/// _ => (chunk * (i + 1)) as u8
2436/// };
2437/// let l_bound = (chunk * i) as u8;
2438/// let perm = get_permutation_for(&data, data.len(), l_bound as usize).unwrap();
2439/// let t_dat : Vec<u8> = perm.iter().map(|v| **v).collect(); // need to move to each thread
2440/// let t_counter = Arc::clone(&complete_count); // thread completed count
2441/// let loc_counter = Arc::clone(&total_counter); // count number of permutation
2442/// thread::spawn(move || {
2443/// let mut counter = 0u64;
2444/// x_permutation(&t_dat, |v| {
2445/// *v[0] >= l_bound && *v[0] < u_bound
2446/// }, |_p| {
2447/// counter += 1;
2448/// });
2449///
2450/// *loc_counter.write().unwrap() += counter;
2451/// println!("Done {} in local thread", counter);
2452/// *t_counter.write().unwrap() += 1;
2453/// });
2454/// }
2455///
2456/// let main = thread::spawn(move || {
2457/// let timer = Instant::now();
2458/// loop {
2459/// if *complete_count.read().unwrap() != (threads as u64) {
2460/// thread::sleep(Duration::from_millis(100));
2461/// } else {
2462/// println!("Done {} x_permutation {} threads in {:?}", &*total_counter.read().unwrap(), threads, timer.elapsed());
2463/// break;
2464/// }
2465/// }
2466/// });
2467///
2468/// main.join().unwrap();
2469/// ```
2470///
2471/// # Parameters
2472/// - d : &[T] - A data to get a permutation.
2473/// - t : FnMut(&[&T]) -> bool - A function for checking whether to traverse the branch.
2474/// It shall return true if the branch need to be traversed.
2475/// - cb : FnMut(&[&T]) - A callback function that return result to caller.
2476pub fn x_permutation<T>(d : &[T], mut t : impl FnMut(&[&T]) -> bool, mut cb : impl FnMut(&[&T])) {
2477 let mut perm : Vec<&T> = (0..d.len()).map(|i| &d[i]).collect();
2478 let perm_ptr = &perm as *const Vec<&T>;
2479 _x_permutation_core(
2480 d,
2481 |i, j| {
2482 perm[i] = &d[j];
2483 }, |k| -> bool {
2484 unsafe { // should be safe as it got called after it mutated
2485 t(&(*perm_ptr)[0..k])
2486 }
2487 }, || { // should be safe as it got called after it mutated
2488 unsafe {
2489 cb(&(*perm_ptr))
2490 }
2491 }
2492 )
2493}
2494
2495/// A lexicographic ordered permutation based on ["Algoritm X" published by
2496/// Donald E. Knuth.](http://www.cs.utsa.edu/~wagner/knuth/fasc2b.pdf) page 20.
2497///
2498/// If order is not important, consider using [heap permutation](fn.heap_permutation_cell.html)
2499/// function instead. This function is 3 times slower than heap [heap
2500/// permutation](fn.heap_permutation_cell.html) in uncontroll test environment.
2501///
2502/// The algorithm work by simulate tree traversal where some branch can be
2503/// skip altogether. This is archive by provided `t` function that take
2504/// slice of partial result as parameter. If the partial result needed to be skip,
2505/// return false. Otherwise, return true and the algorithm will call this function
2506/// again when the branch is descended deeper. For example: First call to `t` may
2507/// contain [1]. If `t` return true, it will be called again with [1, 2]. If it
2508/// return true, and there's leaf node, cb will be called with [1, 2]. On the other hand,
2509/// if `t` is called with [1, 3] and it return false, it won't call the callback.
2510/// If `t` is called with [4] and it return false, it won't try to traverse deeper even
2511/// if there're [4, 5], or [4, 6]. It will skip altogether and call `t` with [7].
2512/// The process goes on until every branch is traversed.
2513///
2514/// # Example
2515/// See [x_permutation document](fn.x_permutation.html) for example.
2516/// It's the same except the way it return result.
2517///
2518/// # Parameters
2519/// - d : &[T] - A data to get a permutation.
2520/// - result : Rc<RefCell<&mut [&T]>> - A result container.
2521/// The result will be overwritten on each call to callback.
2522/// - t : FnMut(&[&T]) -> bool - A function for checking whether to traverse the branch.
2523/// It shall return true if the branch need to be traversed.
2524/// - cb : FnMut() - A callback function that notify caller that new result is available.
2525pub fn x_permutation_cell<'a, T>(d : &'a [T], result : Rc<RefCell<&mut [&'a T]>>,mut t : impl FnMut(&[&T]) -> bool, mut cb : impl FnMut()) {
2526 assert_eq!(result.borrow().len(), d.len(), "`result` shall has length equals to `d`");
2527 { // init result
2528 let mut mutable_res = result.borrow_mut();
2529 (0..d.len()).for_each(|i| mutable_res[i] = &d[i]);
2530 }
2531
2532 _x_permutation_core(
2533 d,
2534 |i, j| {
2535 result.borrow_mut()[i] = &d[j];
2536 }, |k| -> bool {
2537 t(&result.borrow()[0..k])
2538 }, || { // should be safe as it got called after it mutated
2539 cb()
2540 }
2541 )
2542}
2543
2544/// A lexicographic ordered permutation based on ["Algoritm X" published by
2545/// Donald E. Knuth.](http://www.cs.utsa.edu/~wagner/knuth/fasc2b.pdf) page 20.
2546///
2547/// If order is not important, consider using [heap permutation](fn.heap_permutation_sync.html)
2548/// function instead. This function is 3 times slower than heap [heap
2549/// permutation](fn.heap_permutation_sync.html) in uncontroll test environment.
2550///
2551/// The algorithm work by simulate tree traversal where some branch can be
2552/// skip altogether. This is archive by provided `t` function that take
2553/// slice of partial result as parameter. If the partial result needed to be skip,
2554/// return false. Otherwise, return true and the algorithm will call this function
2555/// again when the branch is descended deeper. For example: First call to `t` may
2556/// contain [1]. If `t` return true, it will be called again with [1, 2]. If it
2557/// return true, and there's leaf node, cb will be called with [1, 2]. On the other hand,
2558/// if `t` is called with [1, 3] and it return false, it won't call the callback.
2559/// If `t` is called with [4] and it return false, it won't try to traverse deeper even
2560/// if there're [4, 5], or [4, 6]. It will skip altogether and call `t` with [7].
2561/// The process goes on until every branch is traversed.
2562///
2563/// # Example
2564/// See [x_permutation document](fn.x_permutation.html) for example.
2565/// It's the same except the way it return result.
2566///
2567/// # Parameters
2568/// - d : &[T] - A data to get a permutation.
2569/// - result : Arc<RwLock<Vec<&T>>> - A result container.
2570/// The result will be overwritten on each call to callback.
2571/// - t : FnMut(&[&T]) -> bool - A function for checking whether to traverse the branch.
2572/// It shall return true if the branch need to be traversed.
2573/// - cb : FnMut() - A callback function that notify caller that new result is available.
2574pub fn x_permutation_sync<'a, T>(d : &'a [T], result : Arc<RwLock<Vec<&'a T>>>,mut t : impl FnMut(&[&T]) -> bool, mut cb : impl FnMut()) {
2575 assert_eq!(result.read().unwrap().len(), d.len(), "`result` shall has length equals to `d`");
2576 { // init result
2577 let mut mutable_res = result.write().unwrap();
2578 (0..d.len()).for_each(|i| mutable_res[i] = &d[i]);
2579 }
2580
2581 _x_permutation_core(
2582 d,
2583 |i, j| {
2584 result.write().unwrap()[i] = &d[j];
2585 }, |k| -> bool {
2586 t(&result.read().unwrap()[0..k])
2587 }, || { // should be safe as it got called after it mutated
2588 cb()
2589 }
2590 )
2591}
2592
2593/// A lexicographic ordered permutation based on ["Algoritm X" published by
2594/// Donald E. Knuth.](http://www.cs.utsa.edu/~wagner/knuth/fasc2b.pdf) page 20.
2595///
2596/// If order is not important, consider using [heap permutation](fn.unsafe_heap_permutation.html)
2597/// function instead. This function is 3 times slower than heap [heap
2598/// permutation](fn.unsafe_heap_permutation.html) in uncontroll test environment.
2599///
2600/// The algorithm work by simulate tree traversal where some branch can be
2601/// skip altogether. This is archive by provided `t` function that take
2602/// slice of partial result as parameter. If the partial result needed to be skip,
2603/// return false. Otherwise, return true and the algorithm will call this function
2604/// again when the branch is descended deeper. For example: First call to `t` may
2605/// contain [1]. If `t` return true, it will be called again with [1, 2]. If it
2606/// return true, and there's leaf node, cb will be called with [1, 2]. On the other hand,
2607/// if `t` is called with [1, 3] and it return false, it won't call the callback.
2608/// If `t` is called with [4] and it return false, it won't try to traverse deeper even
2609/// if there're [4, 5], or [4, 6]. It will skip altogether and call `t` with [7].
2610/// The process goes on until every branch is traversed.
2611///
2612/// # Example
2613/// See [x_permutation document](fn.x_permutation.html) for example.
2614/// It's the same except the way it return result.
2615///
2616/// # Parameters
2617/// - d : &[T] - A data to get a permutation.
2618/// - result : *mut [&T] - A result container.
2619/// The result will be overwritten on each call to callback.
2620/// - t : FnMut(&[&T]) -> bool - A function for checking whether to traverse the branch.
2621/// It shall return true if the branch need to be traversed.
2622/// - cb : FnMut() - A callback function that notify caller that new result is available.
2623///
2624/// # Safety
2625/// This function is unsafe to used. This function store result into raw pointer thus all
2626/// unsafe Rust condition may applied. For example, it may seg fault if pointer is invalid.
2627/// It may cause datarace. It may leak memory.
2628///
2629/// # Rationale
2630/// This function permit sharing data to other without cost by sacrifice the safety.
2631/// For safely share result in single thread, consider using
2632/// [x_permutation_cell](fn.x_permutation_cell.html). For safely share result in
2633/// multi-threads, consider using [x_permutation_sync](fn.x_permutation_sync.html).
2634/// Both functions have some cost due to additional safety check.
2635pub unsafe fn unsafe_x_permutation<'a, T>(d : &'a [T], result : *mut [&'a T], mut t : impl FnMut(&[&T]) -> bool, mut cb : impl FnMut()) {
2636 assert_eq!((*result).len(), d.len(), "`result` shall has length equals to `d`");
2637 (0..d.len()).for_each(|i| (*result)[i] = &d[i]);
2638
2639 _x_permutation_core(
2640 d,
2641 |i, j| {
2642 (*result)[i] = &d[j];
2643 }, |k| -> bool {
2644 t(&(*result)[0..k])
2645 }, || { // should be safe as it got called after it mutated
2646 cb()
2647 }
2648 )
2649}
2650
2651/// A trait that add reset function to an existing Iterator.
2652/// It mean that the `next` or `next_into_cell` call will start returning
2653/// the first element again
2654pub trait IteratorReset {
2655 /// Reset an iterator. It make an iterator start from the beginning again.
2656 fn reset(&mut self);
2657}
2658
2659/// Core algorithm of `next` function for all `CartesianProduct` iterator
2660/// family.
2661///
2662/// # Parameters
2663/// 1. `i` - ref mut usize which is cursor pointed to domain inside domains
2664/// 2. `c` - ref mut Vec of usize which is cursor of each domain
2665/// 3. `exhausted` - boolean which if true mean iterator is exhausted
2666/// 4. `n` - number of domains
2667/// 5. `domain_len` - is a closure that take usize and return size of
2668/// the domain at given usize
2669#[inline(always)]
2670fn _cartesian_next_core<'a>(
2671 i : &mut usize,
2672 c : &mut Vec<usize>,
2673 exhausted : &mut bool,
2674 n : usize,
2675 domain_len : impl Fn(usize) -> usize,
2676 mut into_result : impl FnMut(usize, usize) + 'a)
2677{
2678 // move and set `result` and `c` up until all `domains` processed
2679 while *i < n && ! *exhausted {
2680 // if current domain is exhausted.
2681 if c[*i] == domain_len(*i) {
2682 // reset all exhausted domain in `result` and `c`
2683 let mut k = *i;
2684
2685 // reset all exhausted until either found non-exhausted or reach first domain
2686 while c[k] == domain_len(k) && k > 0 {
2687 c[k] = 1;
2688 into_result(k, 0);
2689 k -= 1;
2690 }
2691
2692 if k == 0 && c[k] == domain_len(k) {
2693 // if first domain is also exhausted then flag it.
2694 *exhausted = true;
2695 } else {
2696 // otherwise advance c[k] and set result[k] to next value
2697 // self.result[k] = &self.domains[k][self.c[k]];
2698 into_result(k, c[k]);
2699 c[k] += 1;
2700 }
2701 } else {
2702 // non exhausted domain, advance `c` and set result
2703 // self.result[self.i] = &self.domains[self.i][self.c[self.i]];
2704 into_result(*i, c[*i]);
2705 c[*i] += 1;
2706 }
2707 *i += 1;
2708 }
2709}
2710
2711/// Generate a cartesian product between given domains in an iterator style.
2712/// The struct implement `Iterator` trait so it can be used in `Iterator`
2713/// style. The struct provide [into_iter()](#method.into_iter()) function
2714/// that return itself.
2715///
2716/// # Example
2717/// ```
2718/// use permutator::CartesianProductIterator;
2719/// use std::time::Instant;
2720/// let data : &[&[usize]] = &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
2721/// let cart = CartesianProductIterator::new(&data);
2722/// let mut counter = 0;
2723/// let timer = Instant::now();
2724///
2725/// for p in cart {
2726/// // println!("{:?}", p);
2727/// counter += 1;
2728/// }
2729///
2730/// // or functional style like the line below
2731/// // cart.into_iter().for_each(|p| {/* do something iterative style */});
2732///
2733/// assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
2734/// println!("Total {} products done in {:?}", counter, timer.elapsed());
2735/// ```
2736pub struct CartesianProductIterator<'a, T> where T : 'a {
2737 c : Vec<usize>,
2738 domains : &'a [&'a [T]],
2739 exhausted : bool,
2740 i : usize,
2741
2742 result : Vec<&'a T>
2743}
2744
2745impl<'a, T> CartesianProductIterator<'a, T> where T : 'a {
2746 /// Create a new Cartesian product iterator that create a product between
2747 /// each domain inside `domains`.
2748 /// # Parameters
2749 /// - `domains` A slice of domains to create a cartesian product between
2750 /// each domain inside it.
2751 /// # Return
2752 /// An object that can be iterate over in iterator style.
2753 pub fn new(domains : &'a[&[T]]) -> CartesianProductIterator<'a, T> {
2754
2755 CartesianProductIterator {
2756 c : vec![0; domains.len()],
2757 domains : domains,
2758 exhausted : false,
2759 i : 0,
2760
2761 result : vec![&domains[0][0]; domains.len()]
2762 }
2763 }
2764
2765 /// Consume itself and return without modify it.
2766 /// Typical usecase is `for p in ref_to_this.into_iter() {}`
2767 /// or `ref_to_this.into_iter().for_each(|p| {/* Do something with product */});`
2768 pub fn into_iter(self) -> Self {
2769 self
2770 }
2771}
2772
2773impl<'a, T> Iterator for CartesianProductIterator<'a, T> {
2774 type Item = Vec<&'a T>;
2775
2776 /// Each iteration return a new Vec contains borrowed element inside
2777 /// an Option. The result can be collected by using `collect` method
2778 /// from `Iterator` trait.
2779 ///
2780 /// Return None when exhausted.
2781 fn next(&mut self) -> Option<Vec<&'a T>> {
2782 let domains = self.domains;
2783 let result = &mut self.result;
2784 _cartesian_next_core(
2785 &mut self.i,
2786 &mut self.c,
2787 &mut self.exhausted,
2788 domains.len(),
2789 #[inline(always)]
2790 |k| {
2791 domains[k].len()
2792 },
2793 #[inline(always)]
2794 |i, j| {
2795 result[i] = &domains[i][j];
2796 }
2797 );
2798
2799 if self.exhausted {
2800 None
2801 } else {
2802 self.i -= 1; // rewind `i` back to last domain
2803 Some(result.to_owned())
2804 }
2805 }
2806}
2807
2808impl<'a, T> IteratorReset for CartesianProductIterator<'a, T> {
2809 fn reset(&mut self) {
2810 self.c = vec![0; self.domains.len()];
2811 self.exhausted = false;
2812 self.i = 0;
2813 }
2814}
2815
2816impl<'a, T> ExactSizeIterator for CartesianProductIterator<'a, T> {
2817 fn len(&self) -> usize {
2818 self.domains.iter().fold(1, |cum, d| {cum * d.len()})
2819 }
2820}
2821
2822/// Generate a cartesian product between given domains into Rc<RefCell<&mut [&T]>>
2823/// in an iterator style.
2824/// The struct implement `Iterator` trait so it can be used as `Iterator`.
2825/// The struct provide [into_iter()](#method.into_iter()) function
2826/// that return itself.
2827///
2828/// # Example
2829/// - Iterator style usage
2830/// ```
2831/// use permutator::CartesianProductCellIter;
2832/// use std::cell::RefCell;
2833/// use std::rc::Rc;
2834/// use std::time::Instant;
2835/// let data : Vec<&[usize]> = vec![&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
2836/// let mut result : Vec<&usize> = vec![&data[0][0]; data.len()];
2837/// let shared = Rc::new(RefCell::new(result.as_mut_slice()));
2838/// let cart = CartesianProductCellIter::new(&data, Rc::clone(&shared));
2839/// let mut counter = 0;
2840/// let timer = Instant::now();
2841///
2842/// for _ in cart {
2843/// println!("{:?}", &*shared.borrow());
2844/// counter += 1;
2845/// }
2846///
2847/// // or functional style like the line below
2848/// // cart.into_iter().for_each(|_| {/* do something iterative style */});
2849///
2850/// assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
2851/// println!("Total {} products done in {:?}", counter, timer.elapsed());
2852/// ```
2853pub struct CartesianProductCellIter<'a, T> where T : 'a {
2854 c : Vec<usize>,
2855 domains : &'a [&'a [T]],
2856 exhausted : bool,
2857 i : usize,
2858
2859 result : Rc<RefCell<&'a mut [&'a T]>>
2860}
2861
2862impl<'a, T> CartesianProductCellIter<'a, T> {
2863 pub fn new(data : &'a [&'a [T]], result : Rc<RefCell<&'a mut [&'a T]>>) -> CartesianProductCellIter<'a, T> {
2864 CartesianProductCellIter {
2865 c : vec![0; data.len()],
2866 domains : data,
2867 exhausted : false,
2868 i : 0,
2869
2870 result : result
2871 }
2872 }
2873
2874 pub fn into_iter(self) -> Self {
2875 self
2876 }
2877}
2878
2879impl<'a, T> Iterator for CartesianProductCellIter<'a, T> where T : 'a {
2880 type Item = ();
2881
2882 /// Mimic iterator `next` function but return value into Rc<RefCell<>> that
2883 /// contains mutable slice. It also return an empty Option to tell caller
2884 /// to distinguish if it's put new value or the iterator itself is exhausted.
2885 /// # Paramerter
2886 /// - `result` An Rc<RefCell<>> contains a mutable slice with length equals
2887 /// to number of `domains` given in [CartesianProductIterator::new()](struct.CartesianProductIterator.html#method.new).
2888 /// The value inside result will be updated everytime this function is called
2889 /// until the function return None. The performance using this function is
2890 /// on part with [cartesian_cell function](fn.cartesian_product_cell.html) on uncontrol
2891 /// test environment.
2892 /// # Return
2893 /// New cartesian product between each `domains` inside `result` parameter
2894 /// and also return `Some(())` if result is updated or `None` when there's
2895 /// no new result.
2896 fn next(&mut self) -> Option<()> {
2897 let mut result = self.result.borrow_mut();
2898 let domains = self.domains;
2899 _cartesian_next_core(
2900 &mut self.i,
2901 &mut self.c,
2902 &mut self.exhausted,
2903 domains.len(),
2904 #[inline(always)]
2905 |k| {
2906 domains[k].len()
2907 },
2908 #[inline(always)]
2909 |i, j| {
2910 result[i] = &domains[i][j];
2911 }
2912 );
2913
2914 if self.exhausted {
2915 None
2916 } else {
2917 self.i -= 1; // rewind `i` back to last domain
2918
2919 Some(())
2920 }
2921 }
2922}
2923
2924impl<'a, T> IteratorReset for CartesianProductCellIter<'a, T> {
2925 fn reset(&mut self) {
2926 self.c.iter_mut().for_each(|c| {*c = 0});
2927 self.exhausted = false;
2928 self.i = 0;
2929 }
2930}
2931
2932impl<'a, T> ExactSizeIterator for CartesianProductCellIter<'a, T> {
2933 fn len(&self) -> usize {
2934 self.domains.iter().fold(1, |cum, d| {cum * d.len()})
2935 }
2936}
2937
2938/// An unsafe way to generate a cartesian product between given domains
2939/// into *mut [&T] in an iterator style.
2940/// The struct implement `Iterator` trait so it can be used as `Iterator`.
2941/// The struct provide [into_iter()](#method.into_iter()) function
2942/// that return itself.
2943///
2944/// # Unsafe
2945/// It took mutable pointer to slice in
2946/// [object instantiation](struct.CartesianProductRefIter.html#method.new)
2947/// and convert it upon creation into mutable borrowed slice.
2948/// All unsafe Rust conditions, therefore, applied to entire usage
2949/// of this struct.
2950///
2951/// # Rationale
2952/// It uses unsafe to take a mutable pointer to store the result
2953/// to avoid the cost of using Rc<RefCell<>>.
2954/// In uncontroll test environment, this struct perform a complete
2955/// iteration over 12,960 products in about 110ms where
2956/// [CartesianProductCellIter](struct.CartesianProductCellIter.html)
2957/// took about 130ms.
2958/// This function is very much alike
2959/// [unsafe_cartesian_product function](fn.unsafe_cartesian_product.html)
2960/// but took `Iterator` approach.
2961///
2962/// # Example
2963/// - Iterator style usage
2964/// ```
2965/// use permutator::CartesianProductRefIter;
2966/// use std::time::Instant;
2967/// let data : Vec<&[usize]> = vec![&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
2968/// let mut result : Vec<&usize> = vec![&data[0][0]; data.len()];
2969/// unsafe {
2970/// let cart = CartesianProductRefIter::new(&data, result.as_mut_slice() as *mut [&usize]);
2971/// let mut counter = 0;
2972/// let timer = Instant::now();
2973///
2974/// for _ in cart {
2975/// println!("{:?}", result);
2976/// counter += 1;
2977/// }
2978///
2979/// // or functional style like the line below
2980/// // cart.into_iter().for_each(|_| {/* do something iterative style */});
2981///
2982/// assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
2983/// println!("Total {} products done in {:?}", counter, timer.elapsed());
2984/// }
2985/// ```
2986pub struct CartesianProductRefIter<'a, T> where T : 'a {
2987 c : Vec<usize>,
2988 domains : &'a [&'a [T]],
2989 exhausted : bool,
2990 i : usize,
2991
2992 result : &'a mut [&'a T]
2993}
2994
2995impl<'a, T> CartesianProductRefIter<'a, T> {
2996 /// Create an iterator with mutable pointer to store the product.
2997 /// It is unsafe because it convert mutable pointer into mutable borrowed value
2998 /// upon creating the object.
2999 ///
3000 /// # Parameter
3001 /// - `data` a borrowed slice contains borrowed slices. It's
3002 /// domains of cartesian product operation.
3003 /// - `result` a mutable pointer pointed to the slice that
3004 /// will be used to store the cartesian product result.
3005 /// The length of the slice shall equals to len of data.
3006 ///
3007 /// # Return
3008 /// Each iteration return empty Option and store actual result into
3009 /// `result` given when construct this `Iterator`.
3010 pub unsafe fn new(data : &'a [&'a [T]], result : *mut [&'a T]) -> CartesianProductRefIter<'a, T> {
3011 CartesianProductRefIter {
3012 c : vec![0; data.len()],
3013 domains : data,
3014 exhausted : false,
3015 i : 0,
3016
3017 result : &mut *result
3018 }
3019 }
3020
3021 pub fn into_iter(self) -> Self {
3022 self
3023 }
3024}
3025
3026impl<'a, T> Iterator for CartesianProductRefIter<'a, T> where T : 'a {
3027 type Item = ();
3028
3029 /// Mimic iterator `next` function but return value into Rc<RefCell<>> that
3030 /// contains mutable slice. It also return an empty Option to tell caller
3031 /// to distinguish if it's put new value or the iterator itself is exhausted.
3032 /// # Paramerter
3033 /// - `result` An Rc<RefCell<>> contains a mutable slice with length equals
3034 /// to number of `domains` given in [CartesianProductIterator::new()](struct.CartesianProductIterator.html#method.new).
3035 /// The value inside result will be updated everytime this function is called
3036 /// until the function return None. The performance using this function is
3037 /// on part with [cartesian_cell function](fn.cartesian_product_cell.html) on uncontrol
3038 /// test environment.
3039 /// # Return
3040 /// New cartesian product between each `domains` inside `result` parameter
3041 /// and also return `Some(())` if result is updated or `None` when there's
3042 /// no new result.
3043 fn next(&mut self) -> Option<()> {
3044 let result = &mut self.result;
3045 let domains = self.domains;
3046 _cartesian_next_core(
3047 &mut self.i,
3048 &mut self.c,
3049 &mut self.exhausted,
3050 domains.len(),
3051 #[inline(always)]
3052 |k| {
3053 domains[k].len()
3054 },
3055 #[inline(always)]
3056 |i, j| {
3057 result[i] = &domains[i][j];
3058 }
3059 );
3060
3061 if self.exhausted {
3062 None
3063 } else {
3064 self.i -= 1; // rewind `i` back to last domain
3065
3066 Some(())
3067 }
3068 }
3069}
3070
3071impl<'a, T> IteratorReset for CartesianProductRefIter<'a, T> {
3072 fn reset(&mut self) {
3073 self.c.iter_mut().for_each(|c| {*c = 0});
3074 self.exhausted = false;
3075 self.i = 0;
3076 }
3077}
3078
3079impl<'a, T> ExactSizeIterator for CartesianProductRefIter<'a, T> {
3080 fn len(&self) -> usize {
3081 self.domains.iter().fold(1, |cum, d| {cum * d.len()})
3082 }
3083}
3084
3085/// A core logic of `next` function of `GosperCombination` iterator family.
3086///
3087/// # Parameters
3088/// 1. `map` - a ref mut pointed to gosper map
3089/// 2. `into_result` - closure that take two usizes. First usize is
3090/// incremented on each call by 1. Second usize is index of which
3091/// data that is mapped by gosper's map.
3092#[inline(always)]
3093fn _gosper_next_core(map : &mut u128, mut into_result : impl FnMut(usize, usize)) {
3094 let mut i = 0;
3095 let mut j = 0;
3096 let mut mask = *map;
3097 while mask > 0 {
3098 if mask & 1 == 1 {
3099 into_result(i, j);
3100 i += 1;
3101 }
3102
3103 mask >>= 1;
3104 j += 1;
3105 }
3106
3107 stanford_combination(map);
3108}
3109
3110/// # Deprecated
3111/// This iterator family is now deprecated.
3112/// Consider using [LargeCombinationIterator](struct.LargeCombinationIterator.html)
3113/// instead. This is because current implementation need to copy every ref
3114/// on every iteration which is inefficient.
3115/// On uncontroll test environment, this iterator take 18.98s to iterate over
3116/// 30,045,015 combinations. The [LargeCombinationIterator](struct.LargeCombinationIterator.html)
3117/// took only 2.77s.
3118/// If no more efficient implementation is available for some certain time period,
3119/// this function will be officially mark with #[deprecated].
3120///
3121/// Create a combination iterator.
3122/// It use Gosper's algorithm to pick a combination out of
3123/// given data. The produced combination provide no lexicographic
3124/// order.
3125///
3126/// The returned combination will be a reference into given data.
3127/// Each combination return from iterator will be a new Vec.
3128/// It's safe to hold onto a combination or `collect` it.
3129///
3130/// # Examples
3131/// Given slice of [1, 2, 3, 4, 5]. It will produce following
3132/// combinations:
3133/// [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 5],
3134/// [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]
3135/// Here's an example of code printing above combination.
3136/// ```
3137/// use permutator::GosperCombinationIterator;
3138/// use std::time::{Instant};
3139/// let gosper = GosperCombinationIterator::new(&[1, 2, 3, 4, 5], 3);
3140/// let mut counter = 0;
3141/// let timer = Instant::now();
3142///
3143/// for combination in gosper {
3144/// println!("{}:{:?}", counter, combination);
3145/// counter += 1;
3146/// }
3147///
3148/// println!("Total {} combinations in {:?}", counter, timer.elapsed());
3149/// ```
3150/// # Limitation
3151/// Gosper algorithm need to know the MSB (most significant bit).
3152/// The current largest known MSB data type is u128.
3153/// This make the implementation support up to 128 elements slice.
3154///
3155/// # See
3156/// - [Gospel's algorithm in Wikipedia page, October 9, 2018](https://en.wikipedia.org/wiki/Combinatorial_number_system#Applications)
3157pub struct GosperCombinationIterator<'a, T> where T : 'a {
3158 data : &'a [T], // data to generate a combination
3159 len : usize, // total possible number of combination.
3160 r : usize, // a size of combination.
3161 x : u128, // A binary map to generate combination
3162}
3163
3164impl<'a, T> GosperCombinationIterator<'a, T> {
3165 /// Create new combination generator using Gosper's algorithm.
3166 /// `r` shall be smaller than data.len().
3167 ///
3168 /// Note: It perform no check on given parameter.
3169 /// If r is larger than length of data then iterate over it
3170 /// will not occur. The iteration will be end upon enter.
3171 pub fn new(data : &[T], r : usize) -> GosperCombinationIterator<T> {
3172 let mut x : u128 = 1;
3173 x <<= r;
3174 x -= 1;
3175 let n = data.len();
3176 GosperCombinationIterator {
3177 data : data,
3178 len : divide_factorial(n, n - r) / factorial(r),
3179 r : r,
3180 x : x
3181 }
3182 }
3183
3184 /// Total number of combinations this iterate can return.
3185 /// It will equals to n!/((n-r)!*r!)
3186 pub fn len(&self) -> usize {
3187 self.len
3188 }
3189
3190 pub fn reset(&mut self) {
3191 self.x = 1;
3192 self.x <<= self.r;
3193 self.x -= 1;
3194 }
3195}
3196
3197impl<'a, T> IntoIterator for GosperCombinationIterator<'a, T> {
3198 type Item = Vec<&'a T>;
3199 type IntoIter = CombinationIterator<'a, T>;
3200
3201 fn into_iter(self) -> CombinationIterator<'a, T> {
3202 CombinationIterator {
3203 data : self.data,
3204 r : self.r,
3205 x : self.x
3206 }
3207 }
3208}
3209
3210/// # Deprecated
3211///
3212/// An iterator return from [struct GosperCombination](struct.GosperCombinationIterator.html)
3213/// or from [trait Combination](trait.Combination.html) over slice or vec of data.
3214pub struct CombinationIterator<'a, T> where T : 'a {
3215 data : &'a [T], // original data
3216 r : usize, // len of each combination
3217 x : u128, // Gosper binary map
3218}
3219
3220impl<'a, T> Iterator for CombinationIterator<'a, T> {
3221 type Item = Vec<&'a T>;
3222
3223 fn next(&mut self) -> Option<Vec<&'a T>> {
3224 let mut combination : Vec<&T> = Vec::new();
3225
3226 if 128 - self.x.leading_zeros() as usize > self.data.len() {
3227 return None
3228 }
3229
3230 // stanford_combination(&mut self.x);
3231 let data = self.data;
3232 let map = &mut self.x;
3233 _gosper_next_core(map,
3234 #[inline(always)]
3235 |_, j| {
3236 combination.push(&data[j]);
3237 }
3238 );
3239
3240 return Some(combination)
3241 }
3242}
3243
3244impl<'a, T> IteratorReset for CombinationIterator<'a, T> {
3245 fn reset(&mut self) {
3246 self.x = 1;
3247 self.x <<= self.r;
3248 self.x -= 1;
3249 }
3250}
3251
3252impl<'a, T> ExactSizeIterator for CombinationIterator<'a, T> {
3253 fn len(&self) -> usize {
3254 let n = self.data.len();
3255 divide_factorial(n, multiply_factorial(n - self.r, self.r))
3256 }
3257}
3258
3259/// # Deprecated
3260/// This iterator family is now deprecated.
3261/// Consider using [LargeCombinationCellIter](struct.LargeCombinationCellIter.html)
3262/// instead. This is because current implementation need to copy every ref
3263/// on every iteration which is inefficient.
3264/// On uncontroll test environment, this iterator take 2.49s to iterate over
3265/// 30,045,015 combinations. The [LargeCombinationCellIter](struct.LargeCombinationCellIter.html)
3266/// took only 446.39ms.
3267///
3268/// Create a combination iterator.
3269/// It use Gosper's algorithm to pick a combination out of
3270/// given data. The produced combination provide no lexicographic
3271/// order.
3272///
3273/// The returned combination will be a reference into given data.
3274/// Each combination return from iterator by storing into given
3275/// Rc<RefCell<&mut [&T]>> along with empty Option.
3276///
3277/// # Examples
3278/// Given slice of [1, 2, 3, 4, 5]. It will produce following
3279/// combinations:
3280/// [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 5],
3281/// [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]
3282/// Here's an example of code printing above combination.
3283/// ```
3284/// use permutator::{GosperCombinationCellIter};
3285/// use std::cell::RefCell;
3286/// use std::rc::Rc;
3287/// use std::time::{Instant};
3288/// let data = &[1, 2, 3, 4, 5];
3289/// let mut result : &mut[&i32] = &mut [&data[0]; 3];
3290/// let shared = Rc::new(RefCell::new(result));
3291/// let mut gosper = GosperCombinationCellIter::new(&[1, 2, 3, 4, 5], 3, Rc::clone(&shared));
3292/// let mut counter = 0;
3293/// let timer = Instant::now();
3294///
3295/// for _ in gosper {
3296/// println!("{}:{:?}", counter, shared);
3297/// counter += 1;
3298/// }
3299///
3300/// println!("Total {} combinations in {:?}", counter, timer.elapsed());
3301/// ```
3302///
3303/// # Limitation
3304/// Gosper algorithm need to know the MSB (most significant bit).
3305/// The current largest known MSB data type is u128.
3306/// This make the implementation support up to 128 elements slice.
3307///
3308/// # See
3309/// - [Gospel's algorithm in Wikipedia page, October 9, 2018](https://en.wikipedia.org/wiki/Combinatorial_number_system#Applications)
3310pub struct GosperCombinationCellIter<'a, T> where T : 'a {
3311 data : &'a [T], // data to generate a combination
3312 len : usize, // total possible number of combination.
3313 r : usize, // a size of combination.
3314 x : u128, // A binary map to generate combination
3315
3316 result : Rc<RefCell<&'a mut [&'a T]>>
3317}
3318
3319impl<'a, T> GosperCombinationCellIter<'a, T> {
3320 /// Create new combination generator using Gosper's algorithm.
3321 /// `r` shall be smaller than data.len().
3322 ///
3323 /// Note: It perform no check on given parameter.
3324 /// If r is larger than length of data then iterate over it
3325 /// will not occur. The iteration will be end upon enter.
3326 pub fn new(data : &'a [T], r : usize, result : Rc<RefCell<&'a mut [&'a T]>>) -> GosperCombinationCellIter<'a, T> {
3327 let mut x : u128 = 1;
3328 x <<= r;
3329 x -= 1;
3330 let n = data.len();
3331 GosperCombinationCellIter {
3332 data : data,
3333 len : divide_factorial(n, n - r) / factorial(r),
3334 r : r,
3335 x : x,
3336
3337 result : result
3338 }
3339 }
3340
3341 /// Total number of combinations this iterate can return.
3342 /// It will equals to n!/((n-r)!*r!)
3343 pub fn len(&self) -> usize {
3344 self.len
3345 }
3346}
3347
3348impl<'a, T> IntoIterator for GosperCombinationCellIter<'a, T> {
3349 type Item = ();
3350 type IntoIter = CombinationCellIter<'a, T>;
3351
3352 fn into_iter(self) -> CombinationCellIter<'a, T> {
3353 CombinationCellIter {
3354 data : self.data,
3355 r : self.r,
3356 x : self.x,
3357
3358 result : self.result
3359 }
3360 }
3361}
3362
3363/// # Deprecated
3364///
3365/// An iterator return from [struct GosperCombination](struct.GosperCombinationIterator.html)
3366/// or from [trait Combination](trait.Combination.html) over slice or vec of data.
3367pub struct CombinationCellIter<'a, T> where T : 'a {
3368 data : &'a [T], // original data
3369 r : usize, // len of each combination
3370 x : u128, // Gosper binary map
3371
3372 result : Rc<RefCell<&'a mut[&'a T]>>
3373}
3374
3375impl<'a, T> Iterator for CombinationCellIter<'a, T> {
3376 type Item = ();
3377
3378 fn next(&mut self) -> Option<()> {
3379 if 128 - self.x.leading_zeros() as usize > self.data.len() {
3380 return None
3381 }
3382 // else {
3383 // let mut i = 0;
3384 // let mut j = 0;
3385 // let mut mask = self.x;
3386 // while mask > 0 {
3387 // if mask & 1 == 1 {
3388 // self.result.borrow_mut()[i] = &self.data[j];
3389 // i += 1;
3390 // }
3391
3392 // mask >>= 1;
3393 // j += 1;
3394 // }
3395 // }
3396
3397 // stanford_combination(&mut self.x);
3398
3399 let data = self.data;
3400 let map = &mut self.x;
3401 let mut result = self.result.borrow_mut();
3402 _gosper_next_core(map,
3403 #[inline(always)]
3404 |i, j| {
3405 result[i] = &data[j];
3406 }
3407 );
3408
3409 return Some(())
3410 }
3411}
3412
3413impl<'a, T> IteratorReset for CombinationCellIter<'a, T> {
3414 fn reset(&mut self) {
3415 self.x = 1;
3416 self.x <<= self.r;
3417 self.x -= 1;
3418 }
3419}
3420
3421impl<'a, T> ExactSizeIterator for CombinationCellIter<'a, T> {
3422 fn len(&self) -> usize {
3423 let n = self.data.len();
3424 divide_factorial(n, multiply_factorial(n - self.r, self.r))
3425 }
3426}
3427
3428
3429/// # Deprecated
3430/// This iterator family is now deprecated.
3431/// Consider using [LargeCombinationCellIter](struct.LargeCombinationCellIter.html)
3432/// instead. This is because current implementation need to copy every ref
3433/// on every iteration which is inefficient.
3434/// On uncontroll test environment, this iterator take 2.29s to iterate over
3435/// 30,045,015 combinations. The [LargeCombinationCellIter](struct.LargeCombinationCellIter.html)
3436/// took only 345.44ms.
3437///
3438/// Create an unsafe combination iterator that return result to mutable pointer.
3439/// It use Gosper's algorithm to pick a combination out of
3440/// given data. The produced combination provide no lexicographic
3441/// order.
3442///
3443/// The returned combination will be a reference into given data.
3444/// Each combination return from iterator by storing into given
3445/// *mut [&T] along with empty Option.
3446///
3447/// # Unsafe
3448/// This object took raw mutable pointer and convert in upon object
3449/// instantiation via [new function](struct.GosperCombinationRefIter.html#method.new)
3450/// thus all unsafe Rust conditions will be applied on all method.
3451///
3452/// # Rationale
3453/// It uses unsafe to take a mutable pointer to store the result
3454/// to avoid the cost of using Rc<RefCell<>>.
3455/// In uncontroll test environment, this struct perform a complete
3456/// iteration over 657,800 combinations in about 47ms where
3457/// [GosperCombinationCellIter](struct.GosperCombinationCellIter.html)
3458/// took about 52ms.
3459/// This function is very much alike
3460/// [unsafe_combination function](fn.unsafe_combination.html)
3461/// but took `Iterator` approach.
3462///
3463/// # Examples
3464/// Given slice of [1, 2, 3, 4, 5]. It will produce following
3465/// combinations:
3466/// [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 5],
3467/// [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]
3468/// Here's an example of code printing above combination.
3469/// ```
3470/// use permutator::{GosperCombinationRefIter};
3471/// use std::time::{Instant};
3472/// let data = &[1, 2, 3, 4, 5];
3473/// let mut result : &mut[&i32] = &mut [&data[0]; 3];
3474/// unsafe {
3475/// let mut gosper = GosperCombinationRefIter::new(&[1, 2, 3, 4, 5], 3, result as *mut [&i32]);
3476/// let mut counter = 0;
3477/// let timer = Instant::now();
3478///
3479/// for _ in gosper {
3480/// println!("{}:{:?}", counter, result);
3481/// counter += 1;
3482/// }
3483///
3484/// println!("Total {} combinations in {:?}", counter, timer.elapsed());
3485/// }
3486/// ```
3487///
3488/// # Limitation
3489/// Gosper algorithm need to know the MSB (most significant bit).
3490/// The current largest known MSB data type is u128.
3491/// This make the implementation support up to 128 elements slice.
3492///
3493/// # See
3494/// - [Gospel's algorithm in Wikipedia page, October 9, 2018](https://en.wikipedia.org/wiki/Combinatorial_number_system#Applications)
3495pub struct GosperCombinationRefIter<'a, T> where T : 'a {
3496 data : &'a [T], // data to generate a combination
3497 len : usize, // total possible number of combination.
3498 r : usize, // a size of combination.
3499 x : u128, // A binary map to generate combination
3500
3501 result : &'a mut [&'a T]
3502}
3503
3504impl<'a, T> GosperCombinationRefIter<'a, T> {
3505 /// Create new combination generator using Gosper's algorithm.
3506 /// `r` shall be smaller than data.len().
3507 ///
3508 /// Note: It perform no check on given parameter.
3509 /// If r is larger than length of data then iterate over it
3510 /// will not occur. The iteration will be end upon enter.
3511 pub unsafe fn new(data : &'a [T], r : usize, result : *mut [&'a T]) -> GosperCombinationRefIter<'a, T> {
3512 let mut x : u128 = 1;
3513 x <<= r;
3514 x -= 1;
3515 let n = data.len();
3516 GosperCombinationRefIter {
3517 data : data,
3518 len : divide_factorial(n, n - r) / factorial(r),
3519 r : r,
3520 x : x,
3521
3522 result : &mut *result
3523 }
3524 }
3525
3526 /// Total number of combinations this iterate can return.
3527 /// It will equals to n!/((n-r)!*r!)
3528 pub fn len(&self) -> usize {
3529 self.len
3530 }
3531}
3532
3533impl<'a, T> IntoIterator for GosperCombinationRefIter<'a, T> {
3534 type Item = ();
3535 type IntoIter = CombinationRefIter<'a, T>;
3536
3537 fn into_iter(self) -> CombinationRefIter<'a, T> {
3538 CombinationRefIter {
3539 data : self.data,
3540 r : self.r,
3541 x : self.x,
3542
3543 result : self.result
3544 }
3545 }
3546}
3547
3548/// # Deprecated
3549///
3550/// An iterator return from [struct GosperCombination](struct.GosperCombinationIterator.html)
3551/// or from [trait Combination](trait.Combination.html) over slice or vec of data.
3552pub struct CombinationRefIter<'a, T> where T : 'a {
3553 data : &'a [T], // original data
3554 r : usize, // len of each combination
3555 x : u128, // Gosper binary map
3556
3557 result : &'a mut[&'a T]
3558}
3559
3560impl<'a, T> Iterator for CombinationRefIter<'a, T> {
3561 type Item = ();
3562
3563 fn next(&mut self) -> Option<()> {
3564 if 128 - self.x.leading_zeros() as usize > self.data.len() {
3565 return None
3566 }
3567 // else {
3568 // let mut i = 0;
3569 // let mut j = 0;
3570 // let mut mask = self.x;
3571 // while mask > 0 {
3572 // if mask & 1 == 1 {
3573 // self.result[i] = &self.data[j];
3574 // i += 1;
3575 // }
3576
3577 // mask >>= 1;
3578 // j += 1;
3579 // }
3580 // }
3581
3582 // stanford_combination(&mut self.x);
3583 let data = self.data;
3584 let map = &mut self.x;
3585 let result = &mut self.result;
3586 _gosper_next_core(map,
3587 #[inline(always)]
3588 |i, j| {
3589 result[i] = &data[j];
3590 }
3591 );
3592
3593 return Some(())
3594 }
3595}
3596
3597impl<'a, T> IteratorReset for CombinationRefIter<'a, T> {
3598 fn reset(&mut self) {
3599 self.x = 1;
3600 self.x <<= self.r;
3601 self.x -= 1;
3602 }
3603}
3604
3605impl<'a, T> ExactSizeIterator for CombinationRefIter<'a, T> {
3606 fn len(&self) -> usize {
3607 let n = self.data.len();
3608 divide_factorial(n, multiply_factorial(n - self.r, self.r))
3609 }
3610}
3611
3612/// A core logic of `next` function of `LargeCombination` iterator family.
3613///
3614/// # Parameters
3615/// 1. `c` - a ref mut slice to usize. It's current cursor state in iterator
3616/// 2. `data` - a ref slice to data to get a combination from.
3617/// 3. `iterated` - A ref mut to empty Option. If none, it mean this is first call
3618/// to the function.
3619/// 4. `r` - A size of combination
3620/// 5. `result` - A ref mut to result container
3621/// 6. `result_change_fn` - A closure that accept parameter `usize`, `usize`, and `&mut R`.
3622/// It responsible to assign a new value to R. The first usize is a slot of R
3623/// to be updated. The second usize is the index to `data`.
3624/// 7. `result_fn` - A function that make result ready for comsumption.
3625#[inline(always)]
3626fn _large_comb_next_core<'a, T, R, V>(
3627 c : &mut [usize],
3628 data : & [T],
3629 iterated : &mut Option<()>,
3630 r : usize,
3631 result : &mut R,
3632 mut result_change_fn : impl FnMut(usize, usize, &mut R),
3633 result_fn : impl Fn(&R) -> V
3634) -> Option<V>
3635 where T : 'a,
3636{
3637 /// Move cursor and update result
3638 #[inline(always)]
3639 fn move_cur_res<'a, T, R>(
3640 c : &mut [usize],
3641 domain : &'a [T],
3642 result : &mut R,
3643 mut next_result_fn : impl FnMut(usize, usize, &mut R)
3644 ) -> Option<()> {
3645 let n = c.len();
3646 let max = domain.len();
3647 let mut i = c.len() - 1;
3648
3649 if c[i] < max - n + i {
3650 c[i] += 1;
3651 next_result_fn(i, c[i], result);
3652 Some(())
3653 } else {
3654 // find where to start reset cursor
3655 while c[i] >= max - n + i && i > 0 {
3656 i -= 1;
3657 }
3658
3659 if c[0] >= max - n {
3660 // first slot already on last possible value
3661 return None;
3662 }
3663
3664 c[i] += 1;
3665 next_result_fn(i, c[i], result);
3666 i += 1;
3667 // reset all cursor from `i + 1`
3668 (i..c.len()).for_each(|i| {
3669 c[i] = c[i - 1] + 1;
3670 next_result_fn(i, c[i], result);
3671 });
3672
3673 Some(())
3674 }
3675 }
3676
3677 /// Init first result.
3678 /// It'd be call only once to populate the result
3679 #[inline(always)]
3680 fn init_once<'a, F, R>(
3681 c : &mut [usize],
3682 r : usize,
3683 result : &mut R,
3684 result_change_fn : &mut F
3685 ) -> Option<()>
3686 where for<'r> F : FnMut(usize, usize, &mut R),
3687 {
3688 (0..r).for_each(|i| {
3689 result_change_fn(i, i, result);
3690 c[i] = i;
3691 });
3692
3693 return Some(());
3694 }
3695
3696 if let None = iterated {
3697 *iterated = Some(());
3698
3699 init_once(c, r, result, &mut result_change_fn);
3700
3701 // handle special case where data.len() == 1
3702 if data.len() == 1 {
3703 c[0] = 1; // force cursor to go move or next call will reinit result
3704 }
3705
3706 return Some(result_fn(&*result));
3707 }
3708
3709 match move_cur_res(c, data, result, result_change_fn) {
3710 Some(_) => Some(result_fn(&*result)),
3711 None => None
3712 }
3713}
3714
3715/// Create a combination iterator.
3716/// The result is lexicographic ordered if input is lexicorgraphic ordered.
3717/// The returned combination will be a reference into given data.
3718/// Each combination return from iterator will be a new Vec.
3719/// It's safe to hold onto a combination or `collect` it.
3720///
3721/// # Examples
3722/// Given slice of [1, 2, 3, 4, 5]. It will produce following
3723/// combinations:
3724/// [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 5],
3725/// [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]
3726/// Here's an example of code printing above combination.
3727/// ```
3728/// use permutator::LargeCombinationIterator;
3729/// use std::time::{Instant};
3730/// let lc = LargeCombinationIterator::new(&[1, 2, 3, 4, 5], 3);
3731/// let mut counter = 0;
3732/// let timer = Instant::now();
3733///
3734/// for combination in lc {
3735/// println!("{}:{:?}", counter, combination);
3736/// counter += 1;
3737/// }
3738///
3739/// println!("Total {} combinations in {:?}", counter, timer.elapsed());
3740/// ```
3741///
3742/// # Panic
3743/// It panic if `r == 0` or `r > data.len()`
3744pub struct LargeCombinationIterator<'a, T> where T : 'a {
3745 c : Vec<usize>, // cursor for each combination slot
3746 data : &'a [T], // data to generate a combination
3747 i : usize, // slot index being mutate.
3748 nexted : Option<()>, // If iterated at least once, it'd be Some(()). Otherwise, None.
3749 len : usize, // total possible number of combination.
3750 r : usize, // a size of combination.
3751 result : Vec<&'a T>, // result container
3752}
3753
3754impl<'a, T> LargeCombinationIterator<'a, T> {
3755 pub fn new(data : &[T], r : usize) -> LargeCombinationIterator<T> {
3756 assert_ne!(r, 0);
3757 assert!(r <= data.len());
3758
3759 let c = vec![0; r];
3760 let n = data.len();
3761 let result = vec![&data[0]; r];
3762
3763 LargeCombinationIterator {
3764 c,
3765 data : data,
3766 i : 0,
3767 nexted : None,
3768 len : divide_factorial(n, n - r) / factorial(r),
3769 r : r,
3770 result : result
3771 }
3772 }
3773
3774 pub fn iter(&mut self) -> &mut Self {
3775 self
3776 }
3777}
3778
3779impl<'a, T> Iterator for LargeCombinationIterator<'a, T> {
3780 type Item = Vec<&'a T>;
3781
3782 fn next(&mut self) -> Option<Vec<&'a T>> {
3783 let data = &self.data;
3784 _large_comb_next_core(
3785 &mut self.c,
3786 data,
3787 &mut self.nexted,
3788 self.r,
3789 &mut self.result,
3790 |i, j, r| {
3791 r[i] = &data[j];
3792 },
3793 |r| {
3794 r.to_owned()
3795 }
3796 )
3797 }
3798}
3799
3800impl<'a, T> IteratorReset for LargeCombinationIterator<'a, T> {
3801 fn reset(&mut self) {
3802 self.nexted = None;
3803 self.c.iter_mut().for_each(|c| *c = 0);
3804 self.i = 0;
3805 }
3806}
3807
3808impl<'a, T> ExactSizeIterator for LargeCombinationIterator<'a, T> {
3809 fn len(&self) -> usize {
3810 self.len
3811 }
3812}
3813
3814/// Create a combination iterator.
3815/// The result is lexicographic ordered if input is lexicorgraphic ordered.
3816/// The returned combination will be a reference into given data.
3817/// Each combination return from iterator is stored into given
3818/// Rc<RefCell<&mut [&T]>>.
3819///
3820/// The result will be overwritten on every iteration.
3821/// To reuse a result, convert a result to owned value.
3822/// If most result need to be reused, consider using
3823/// [LargeCombinationIterator](struct.LargeCombinationIterator.html)
3824///
3825/// # Examples
3826/// Given slice of [1, 2, 3, 4, 5]. It will produce following
3827/// combinations:
3828/// [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 5],
3829/// [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]
3830/// Here's an example of code printing above combination.
3831/// ```
3832/// use permutator::{LargeCombinationCellIter};
3833/// use std::cell::RefCell;
3834/// use std::rc::Rc;
3835/// use std::time::{Instant};
3836/// let data = &[1, 2, 3, 4, 5];
3837/// let mut result : &mut[&i32] = &mut [&data[0]; 3];
3838/// let shared = Rc::new(RefCell::new(result));
3839/// let mut lc = LargeCombinationCellIter::new(&[1, 2, 3, 4, 5], 3, Rc::clone(&shared));
3840/// let mut counter = 0;
3841/// let timer = Instant::now();
3842///
3843/// for _ in lc {
3844/// println!("{}:{:?}", counter, shared);
3845/// counter += 1;
3846/// }
3847///
3848/// println!("Total {} combinations in {:?}", counter, timer.elapsed());
3849/// ```
3850///
3851/// # Panic
3852/// It panic if `r > data.len()` or `r == 0`
3853pub struct LargeCombinationCellIter<'a, T> where T : 'a {
3854 c : Vec<usize>, // cursor for each combination slot
3855 data : &'a [T], // data to generate a combination
3856 i : usize, // slot index being mutate.
3857 nexted : Option<()>, // If iterated at least once, it'd be Some(()). Otherwise, None.
3858 len : usize, // total possible number of combination.
3859 r : usize, // a size of combination.
3860
3861 result : Rc<RefCell<&'a mut [&'a T]>>
3862}
3863
3864impl<'a, T> LargeCombinationCellIter<'a, T> {
3865 pub fn new(data : &'a [T], r : usize, result : Rc<RefCell<&'a mut [&'a T]>>) -> LargeCombinationCellIter<'a, T> {
3866 assert_ne!(r, 0);
3867 assert!(r <= data.len());
3868
3869 let c = vec![0; r];
3870 let n = data.len();
3871
3872 LargeCombinationCellIter {
3873 c,
3874 data : data,
3875 i : 0,
3876 nexted : None,
3877 len : divide_factorial(n, n - r) / factorial(r),
3878 r : r,
3879
3880 result : result
3881 }
3882 }
3883
3884 pub fn iter(&mut self) -> &mut Self {
3885 self
3886 }
3887}
3888
3889impl<'a, T> Iterator for LargeCombinationCellIter<'a, T> {
3890 type Item = ();
3891
3892 fn next(&mut self) -> Option<()> {
3893 let data = &self.data;
3894 _large_comb_next_core(
3895 &mut self.c,
3896 data,
3897 &mut self.nexted,
3898 self.r,
3899 &mut self.result,
3900 |i, j, r| {
3901 r.borrow_mut()[i] = &data[j];
3902 },
3903 |_| {
3904 ()
3905 }
3906 )
3907 }
3908}
3909
3910impl<'a, T> IteratorReset for LargeCombinationCellIter<'a, T> {
3911 fn reset(&mut self) {
3912 self.nexted = None;
3913 self.c.iter_mut().for_each(|c| *c = 0);
3914 self.i = 0;
3915 }
3916}
3917
3918impl<'a, T> ExactSizeIterator for LargeCombinationCellIter<'a, T> {
3919 fn len(&self) -> usize {
3920 self.len
3921 }
3922}
3923
3924/// Create an unsafe combination iterator that return result to mutable pointer.
3925/// The result is lexicographic ordered if input is lexicorgraphic ordered.
3926/// The returned combination will be a reference into given data.
3927/// Each combination return from iterator is stored into given
3928/// *mut [&T].
3929///
3930/// The result will be overwritten on every iteration.
3931/// To reuse a result, convert a result to owned value.
3932/// If most result need to be reused, consider using
3933/// [LargeCombinationIterator](struct.LargeCombinationIterator.html)
3934///
3935/// # Safety
3936/// This object took raw mutable pointer and convert in upon object
3937/// instantiation via [new function](struct.LargeCombinationRefIter.html#method.new)
3938/// thus all unsafe Rust conditions will be applied on all method.
3939///
3940/// # Rationale
3941/// It uses unsafe to take a mutable pointer to store the result
3942/// to avoid the cost of using Rc<RefCell<>>.
3943/// In uncontroll test environment, this struct perform a complete
3944/// iteration over 30,045,015 combinations in about 337ms where
3945/// [LargeCombinationCellIter](struct.LargeCombinationCellIter.html)
3946/// took about 460ms.
3947/// This function is very much alike
3948/// [unsafe_combination function](fn.unsafe_combination.html)
3949/// but took `Iterator` approach.
3950///
3951/// # Examples
3952/// Given slice of [1, 2, 3, 4, 5]. It will produce following
3953/// combinations:
3954/// [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 5],
3955/// [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]
3956/// Here's an example of code printing above combination.
3957/// ```
3958/// use permutator::{LargeCombinationRefIter};
3959/// use std::time::{Instant};
3960/// let data = &[1, 2, 3, 4, 5];
3961/// let mut result : &mut[&i32] = &mut [&data[0]; 3];
3962/// unsafe {
3963/// let mut comb = LargeCombinationRefIter::new(&[1, 2, 3, 4, 5], 3, result as *mut [&i32]);
3964/// let mut counter = 0;
3965/// let timer = Instant::now();
3966///
3967/// for _ in comb {
3968/// println!("{}:{:?}", counter, result);
3969/// counter += 1;
3970/// }
3971///
3972/// println!("Total {} combinations in {:?}", counter, timer.elapsed());
3973/// }
3974/// ```
3975pub struct LargeCombinationRefIter<'a, T> where T : 'a {
3976 c : Vec<usize>, // cursor for each combination slot
3977 data : &'a [T], // data to generate a combination
3978 i : usize, // slot index being mutate.
3979 nexted : Option<()>, // If iterated at least once, it'd be Some(()). Otherwise, None.
3980 len : usize, // total possible number of combination.
3981 r : usize, // a size of combination.
3982
3983 result : &'a mut [&'a T]
3984}
3985
3986impl<'a, T> LargeCombinationRefIter<'a, T> {
3987 pub unsafe fn new(data : &'a [T], r : usize, result : *mut [&'a T]) -> LargeCombinationRefIter<'a, T> {
3988 assert_ne!(r, 0);
3989 assert!(r <= (*data).len());
3990
3991 let c = vec![0; r];
3992 let n = data.len();
3993
3994 LargeCombinationRefIter {
3995 c,
3996 data : data,
3997 i : 0,
3998 nexted : None,
3999 len : divide_factorial(n, n - r) / factorial(r),
4000 r : r,
4001
4002 result : &mut *result
4003 }
4004 }
4005
4006 /// Total number of combinations this iterate can return.
4007 /// It will equals to n!/((n-r)!*r!)
4008 pub fn len(&self) -> usize {
4009 self.len
4010 }
4011
4012 pub fn iter(&mut self) -> &mut Self {
4013 self
4014 }
4015}
4016
4017impl<'a, T> Iterator for LargeCombinationRefIter<'a, T> {
4018 type Item = ();
4019
4020 fn next(&mut self) -> Option<()> {
4021 let data = &self.data;
4022 _large_comb_next_core(
4023 &mut self.c,
4024 data,
4025 &mut self.nexted,
4026 self.r,
4027 &mut self.result,
4028 |i, j, r| {
4029 r[i] = &data[j];
4030 },
4031 |_| {
4032 ()
4033 }
4034 )
4035 }
4036}
4037
4038impl<'a, T> IteratorReset for LargeCombinationRefIter<'a, T> {
4039 fn reset(&mut self) {
4040 self.nexted = None;
4041 self.c.iter_mut().for_each(|c| *c = 0);
4042 self.i = 0;
4043 }
4044}
4045
4046impl<'a, T> ExactSizeIterator for LargeCombinationRefIter<'a, T> {
4047 fn len(&self) -> usize {
4048 self.len
4049 }
4050}
4051
4052/// Core logic of `next` function of `HeapPermutation` iterator family.
4053///
4054/// # Parameters
4055/// 1. `c` - mutable slice of usize. A cursor that pointed to data for
4056/// each permutation slot.
4057/// 2. `i` - the current index pointed to which slot to be permuted.
4058/// 3. `n` - the number of data/slots to be permuted.
4059#[inline(always)]
4060fn _heap_next_core(
4061 c : &mut[usize],
4062 i : &mut usize,
4063 n : usize,
4064 mut swap_fn : impl FnMut(usize, usize))
4065{
4066 while *i < n {
4067 if c[*i] < *i {
4068 if *i % 2 == 0 {
4069 // self.data.swap(0, *i);
4070 swap_fn(0, *i);
4071 } else {
4072 swap_fn(c[*i], *i);
4073 }
4074
4075 c[*i] += 1;
4076 *i = 0;
4077 return
4078 } else {
4079 c[*i] = 0;
4080 *i += 1;
4081 }
4082 }
4083}
4084
4085/// Heap's permutation in iterator style implementation.
4086///
4087/// # Examples
4088/// Iterator style usage example:
4089/// ```
4090/// use permutator::HeapPermutationIterator;
4091/// use std::time::{Instant};
4092/// let data = &mut [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
4093/// println!("0:{:?}", data);
4094/// let mut permutator = HeapPermutationIterator::new(data);
4095/// let timer = Instant::now();
4096/// let mut counter = 1;
4097///
4098/// for permutated in permutator {
4099/// // println!("{}:{:?}", counter, permutated);
4100/// counter += 1;
4101/// }
4102///
4103/// // or use iterator related functional approach like line below.
4104/// // permutator.into_iter().for_each(|permutated| {counter += 1;});
4105///
4106/// println!("Done {} permutations in {:?}", counter, timer.elapsed());
4107/// ```
4108/// # See
4109/// - [Heap's algorithm in Wikipedia page, October 9, 2018](https://en.wikipedia.org/wiki/Heap%27s_algorithm)
4110pub struct HeapPermutationIterator<'a, T> where T : 'a {
4111 c : Box<[usize]>,
4112 data : &'a mut [T],
4113 i : usize
4114}
4115
4116impl<'a, T> HeapPermutationIterator<'a, T> {
4117 /// Construct a new permutation iterator.
4118 /// Note: the provided parameter will get mutated
4119 /// in placed at first call to next.
4120 pub fn new(data : &mut [T]) -> HeapPermutationIterator<T> {
4121 HeapPermutationIterator {
4122 c : vec![0; data.len()].into_boxed_slice(),
4123 data : data,
4124 i : 0
4125 }
4126 }
4127
4128 /// Consume itself immediately return it.
4129 /// It mimic how `IntoIterator` trait perform except
4130 /// that this struct itself implement `Iterator` trait.
4131 pub fn into_iter(self) -> Self {
4132 self
4133 }
4134}
4135
4136impl<'a, T> Iterator for HeapPermutationIterator<'a, T> where T : Clone {
4137 type Item = Vec<T>;
4138
4139 fn next(&mut self) -> Option<Self::Item> {
4140 let HeapPermutationIterator {ref mut c, ref mut data, ref mut i } = self;
4141 let n = data.len();
4142 let mut result : Option<Vec<T>> = None;
4143 _heap_next_core(c, i, n,
4144 #[inline(always)]
4145 |from, to| {
4146 data.swap(from, to);
4147 result = Some(data.to_owned());
4148 }
4149 );
4150
4151 result
4152 }
4153}
4154
4155impl<'a, T> IteratorReset for HeapPermutationIterator<'a, T> {
4156 /// Reset this permutator so calling next will continue
4157 /// permutation on current permuted data.
4158 /// It will not reset permuted data.
4159 fn reset(&mut self) {
4160 self.i = 0;
4161 self.c.iter_mut().for_each(|c| {*c = 0;});
4162 }
4163}
4164
4165impl<'a, T> ExactSizeIterator for HeapPermutationIterator<'a, T> where T : Clone {
4166 fn len(&self) -> usize {
4167 factorial(self.data.len())
4168 }
4169}
4170
4171/// Heap's permutation in Rc<RefCell<>> mimic Iterator style.
4172/// It provides another choice for user that want to share
4173/// permutation result but doesn't want to clone it for
4174/// each share. It also doesn't create new result on each
4175/// iteration unlike other object that implement `Iterator` trait.
4176/// # Rationale
4177/// Unlike all other struct, HeapPermutationIterator permute value in place.
4178/// If HeapPermutationIterator struct implement IteratorCell itself will
4179/// result in the `data` inside struct left unused.
4180/// This struct introduce the same concept to other struct that
4181/// implement `IteratorCell`, to be able to easily share
4182/// result with as less performance overhead as possible.
4183///
4184/// The implementation take Rc<RefCell<&mut [T]>> instead of regular
4185/// slice like other permutation struct.
4186/// It implements `Iterator` trait with empty associated type because
4187/// it doesn't return value. It permutes the data in place thus
4188/// every owner of Rc<RefCell<&mut [T]>> will always has an up-to-date
4189/// slice.
4190/// # Examples
4191/// Iterator style usage example:
4192/// ```
4193/// use permutator::HeapPermutationCellIter;
4194/// use std::cell::RefCell;
4195/// use std::rc::Rc;
4196/// use std::time::{Instant};
4197/// let data : &mut [i32] = &mut [1, 2, 3, 4, 5];
4198/// let shared = Rc::new(RefCell::new(data));
4199/// let mut permutator = HeapPermutationCellIter::new(Rc::clone(&shared));
4200/// println!("0:{:?}", &*shared.borrow());
4201/// let timer = Instant::now();
4202/// let mut counter = 1;
4203///
4204/// for _ in permutator { // it return empty
4205/// println!("{}:{:?}", counter, &*shared.borrow());
4206/// counter += 1;
4207/// }
4208///
4209/// // or use iterator related functional approach like line below.
4210/// // permutator.into_iter().for_each(|_| {
4211/// // println!("{}:{:?}", counter, &*data.borrow());
4212/// // counter += 1;
4213/// // });
4214///
4215/// println!("Done {} permutations in {:?}", counter, timer.elapsed());
4216/// ```
4217/// # See
4218/// - [HeapPermutationIterator struct](struct.HeapPermutationIterator.html)
4219pub struct HeapPermutationCellIter<'a, T> where T : 'a {
4220 c : Vec<usize>,
4221 data : Rc<RefCell<&'a mut[T]>>,
4222 i : usize
4223}
4224
4225impl<'a, T> HeapPermutationCellIter<'a, T> {
4226 /// Construct a new permutation iterator.
4227 /// Note: the provided parameter will get mutated
4228 /// in placed at first call to next.
4229 pub fn new(data : Rc<RefCell<&'a mut[T]>>) -> HeapPermutationCellIter<'a, T> {
4230 HeapPermutationCellIter {
4231 c : vec![0; data.borrow().len()],
4232 data : Rc::clone(&data),
4233 i : 0
4234 }
4235 }
4236}
4237
4238impl<'a, T> Iterator for HeapPermutationCellIter<'a, T> where T : 'a {
4239 type Item= ();
4240
4241 fn next(&mut self) -> Option<()> {
4242 let HeapPermutationCellIter {ref mut c, ref mut data, ref mut i } = self;
4243 let n = data.borrow().len();
4244 let mut result : Option<()> = None;
4245 _heap_next_core(c, i, n,
4246 #[inline(always)]
4247 |from, to| {
4248 data.borrow_mut().swap(from, to);
4249 result = Some(());
4250 }
4251 );
4252
4253 result
4254 }
4255}
4256
4257impl<'a, T> IteratorReset for HeapPermutationCellIter<'a, T> {
4258 /// Reset this permutator so calling next will continue
4259 /// permutation on current permuted data.
4260 /// It will not reset permuted data.
4261 fn reset(&mut self) {
4262 self.i = 0;
4263 self.c.iter_mut().for_each(|c| {*c = 0;});
4264 }
4265}
4266
4267impl<'a, T> ExactSizeIterator for HeapPermutationCellIter<'a, T> {
4268 fn len(&self) -> usize {
4269 factorial(self.data.borrow().len())
4270 }
4271}
4272
4273/// An unsafe Heap's permutation in iterator style implementation.
4274///
4275/// # Examples
4276/// - Iterator style usage example:
4277/// ```
4278/// use permutator::HeapPermutationRefIter;
4279/// use std::time::{Instant};
4280/// let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
4281/// println!("0:{:?}", data);
4282/// unsafe {
4283/// let mut permutator = HeapPermutationRefIter::new(data as *mut[i32]);
4284/// let timer = Instant::now();
4285/// let mut counter = 1;
4286///
4287/// for permutated in permutator {
4288/// println!("{}:{:?}", counter, permutated);
4289/// counter += 1;
4290/// }
4291///
4292/// // or use iterator related functional approach like line below.
4293/// // permutator.into_iter().for_each(|permutated| {counter += 1;});
4294///
4295/// println!("Done {} permutations in {:?}", counter, timer.elapsed());
4296/// }
4297/// ```
4298/// In test environment, given a slice of 8 strings. It has about 40 characters each.
4299/// This implementation is about 70 times (33ms vs 0.47ms) faster than a [HeapPermutation](struct.HeapPermutation.html)
4300/// iteration. This is because each `next` function doesn't clone/copy the value.
4301/// However, this implementation limited the way to use data because each iteration
4302/// permute the result in place. It require user to manually sync the share operation.
4303/// # See
4304/// - [Heap's algorithm in Wikipedia page, October 9, 2018](https://en.wikipedia.org/wiki/Heap%27s_algorithm)
4305pub struct HeapPermutationRefIter<'a, T> where T : 'a {
4306 c : Vec<usize>,
4307 data : &'a mut [T],
4308 i : usize
4309}
4310
4311impl<'a, T> HeapPermutationRefIter<'a, T> {
4312 /// Construct a new permutation iterator.
4313 /// Note: the provided parameter will get mutated
4314 /// in placed at first call to next.
4315 pub unsafe fn new(data : *mut [T]) -> HeapPermutationRefIter<'a, T> {
4316 HeapPermutationRefIter {
4317 c : vec![0; (*data).len()],
4318 data : &mut *data,
4319 i : 0
4320 }
4321 }
4322
4323 /// Consume itself immediately return it.
4324 /// It mimic how `IntoIterator` trait perform except
4325 /// that this struct itself implement `Iterator` trait.
4326 pub fn into_iter(self) -> Self {
4327 self
4328 }
4329}
4330
4331impl<'a, T> Iterator for HeapPermutationRefIter<'a, T> {
4332 type Item = ();
4333
4334 fn next(&mut self) -> Option<Self::Item> {
4335 let HeapPermutationRefIter {ref mut c, ref mut data, ref mut i } = self;
4336 let n = data.len();
4337 let mut result : Option<()> = None;
4338 _heap_next_core(c, i, n,
4339 #[inline(always)]
4340 |from, to| {
4341 data.swap(from, to);
4342 result = Some(());
4343 }
4344 );
4345
4346 result
4347 }
4348}
4349
4350impl<'a, T> IteratorReset for HeapPermutationRefIter<'a, T> {
4351 /// Reset this permutator so calling next will continue
4352 /// permutation on current permuted data.
4353 /// It will not reset permuted data.
4354 fn reset(&mut self) {
4355 self.i = 0;
4356 self.c.iter_mut().for_each(|c| {*c = 0;});
4357 }
4358}
4359
4360impl<'a, T> ExactSizeIterator for HeapPermutationRefIter<'a, T> {
4361 fn len(&self) -> usize {
4362 factorial(self.data.len())
4363 }
4364}
4365
4366/// k-permutation iterator common code to perform
4367/// `next` element operation.
4368///
4369/// # Parameters
4370/// 1. `combinator` - A combination iterator object
4371/// 2. `permutator` - An Option holding permutation iterator object
4372/// 4. `new_permutator_fn` - A closure that create new permutation iterator
4373#[inline(always)]
4374fn _k_permutation_next_core<'a, T, U, V, W, X>(
4375 combinator : T,
4376 permutator : &'a mut Option<U>,
4377 permuted : X,
4378 new_permutator_fn : impl FnOnce(&'a mut Option<U>, X, V) + 'a
4379) -> Option<()>
4380where T : Iterator<Item=V> + 'a,
4381 U : Iterator<Item=W> + IteratorReset + 'a,
4382 V : 'a,
4383 X : 'a
4384{
4385 #[inline(always)]
4386 fn get_next<'a, T, U, V, W, X>(
4387 combinator : T,
4388 permutator : &'a mut Option<U>,
4389 permuted : X,
4390 new_permutator_fn : impl FnOnce(&'a mut Option<U>, X, V)
4391 ) -> Option<()>
4392 where T : Iterator<Item=V> + 'a,
4393 U : Iterator<Item=W> + IteratorReset + 'a,
4394 V : 'a,
4395 X : 'a
4396 {
4397 if let Some(ref mut perm) = *permutator {
4398 // permutator already exist
4399
4400 if let Some(_) = perm.next() {
4401 // get next permutation of current permutator
4402 return Some(());
4403 }
4404 }
4405
4406 // permutator is not exist yet.
4407 if let Ok(_) = next_permutator(combinator, permutator, permuted, new_permutator_fn) {
4408 // success create new permutator
4409 Some(())
4410 } else {
4411 // no more combination to permute
4412 return None;
4413 }
4414 }
4415
4416 #[inline(always)]
4417 fn next_permutator<'a, T, U, V, W, X>(
4418 mut combinator : T,
4419 permutator : &'a mut Option<U>,
4420 permuted : X,
4421 new_permutator_fn : impl FnOnce(&'a mut Option<U>, X, V)
4422 ) -> Result<(), ()>
4423 where T : Iterator<Item = V> + 'a,
4424 U : Iterator<Item=W> + IteratorReset + 'a,
4425 V : 'a,
4426 X : 'a
4427 {
4428 if let Some(v) = combinator.next() {
4429 new_permutator_fn(&mut *permutator, permuted, v);
4430 Ok(())
4431 } else {
4432 Err(())
4433 }
4434 }
4435
4436 get_next(combinator, permutator, permuted, new_permutator_fn)
4437}
4438
4439/// k-Permutation over data of length n where k must be
4440/// less than n.
4441/// It'll attempt to permute given data by pick `k` elements
4442/// out of data. It use Gosper algorithm to pick the elements.
4443/// It then use Heap's algorithm to permute those `k` elements
4444/// and return each permutation back to caller.
4445///
4446/// # Examples
4447/// - Iterator style permit using 'for-in' style loop along with
4448/// enable usage of functional paradigm over iterator object.
4449/// ```
4450/// use permutator::KPermutationIterator;
4451/// use std::time::Instant;
4452/// let data = [1, 2, 3, 4, 5];
4453/// let permutator = KPermutationIterator::new(&data, 3);
4454/// let mut counter = 0;
4455/// // println!("Begin testing KPermutation");
4456/// let timer = Instant::now();
4457///
4458/// for permuted in permutator {
4459/// // uncomment a line below to print all permutation.
4460/// // println!("{}:{:?}", counter, permuted);
4461/// counter += 1;
4462/// }
4463///
4464/// // Or simply use functional paradigm of iterator like below
4465/// // permutator.into_iter().any(|item| {item == [7, 8, 9]});
4466///
4467/// println!("Total {} permutations done in {:?}", counter, timer.elapsed());
4468/// assert_eq!(60, counter);
4469/// ```
4470///
4471/// # Notes
4472/// The additional functionality provided by this struct is that it can be
4473/// pause or completely stop midway while the [k-permutation](fn.k_permutation.html)
4474/// need to be run from start to finish only.
4475///
4476/// # Safety
4477/// This struct implementation use unsafe code internally.
4478/// It use unsafe because it uses `Vec<T>` to own a combination
4479/// for each permutation. Rust cannot derive lifetime of mutable
4480/// slice created inside next and store it into struct object itself.
4481/// This is because `next` signature have no lifetime associated
4482/// with `self`. To get around this, the implementation convert
4483/// Vec<T> to `*mut [T]` then perform `&mut *` on it.
4484///
4485/// # See
4486/// - [GosperCombination](struct.GoserPermutation.html)
4487/// - [HeapPermutation](struct.HeapPermutationIterator.html)
4488pub struct KPermutationIterator<'a, T> where T : 'a {
4489 permuted : Vec<&'a T>,
4490
4491 len : usize,
4492
4493 combinator : LargeCombinationIterator<'a, T>,
4494 permutator : Option<HeapPermutationIterator<'a, &'a T>>
4495}
4496
4497impl<'a, T> KPermutationIterator<'a, T> {
4498 pub fn new(data : &[T], k : usize) -> KPermutationIterator<T> {
4499 assert_ne!(k, 0);
4500 assert!(k <= data.len());
4501 let combinator = LargeCombinationIterator::new(data, k);
4502 let n = data.len();
4503 let permuted = vec![&data[0]; k];
4504
4505 KPermutationIterator {
4506 permuted : permuted,
4507
4508 len : divide_factorial(n, n - k),
4509
4510 combinator : combinator,
4511 permutator : None
4512 }
4513 }
4514
4515 /// Consume then return self immediately.
4516 /// It permit functional style operation over iterator
4517 /// from borrow object as Rust isn't yet support
4518 /// `for _ in borrowed_object` directly.
4519 /// It need to be `for _ in borrowed_object.into_iter()`.
4520 pub fn into_iter(self) -> Self {
4521 self
4522 }
4523}
4524
4525impl<'a, T> Iterator for KPermutationIterator<'a, T> {
4526 type Item = Vec<&'a T>;
4527
4528 fn next(&mut self) -> Option<Vec<&'a T>> {
4529 let combinator = &mut self.combinator;
4530 let permutator = &mut self.permutator;
4531 let permuted = self.permuted.as_mut_slice() as *mut [&T];
4532
4533 unsafe {
4534 if let Some(_) = _k_permutation_next_core(
4535 combinator,
4536 permutator,
4537 &mut *permuted,
4538 #[inline(always)]
4539 |permutator, permuted, comb| {
4540 permuted.copy_from_slice(comb.as_slice());
4541 *permutator = Some(HeapPermutationIterator::new(permuted));
4542 }
4543 ) {
4544 Some(self.permuted.to_owned())
4545 } else {
4546 None
4547 }
4548 }
4549 }
4550}
4551
4552impl<'a, T> IteratorReset for KPermutationIterator<'a, T> {
4553 fn reset(&mut self) {
4554 self.combinator.reset();
4555 self.permutator = None;
4556 }
4557}
4558
4559impl<'a, T> ExactSizeIterator for KPermutationIterator<'a, T> {
4560 fn len(&self) -> usize {
4561 self.len
4562 }
4563}
4564
4565/// k-Permutation over data of length "n" where `k` must be
4566/// less than `n`.
4567/// It'll attempt to permute given data by pick `k` elements
4568/// out of `n` data. It use Gosper algorithm to pick the elements.
4569/// It then use Heap's algorithm to permute those `k` elements
4570/// and return each permutation back to caller by given
4571/// Rc<RefCell<&mut [&T]>> parameter to
4572/// [new method of KPermutationCellIter](struct.KPermutationCellIter.html#method.new).
4573///
4574/// # Examples
4575/// - Iterator style permit using 'for-in' style loop along with
4576/// enable usage of functional paradigm over iterator object.
4577/// ```
4578/// use permutator::{KPermutationCellIter, IteratorReset};
4579/// use std::cell::RefCell;
4580/// use std::rc::Rc;
4581/// use std::time::Instant;
4582/// let data = [1, 2, 3, 4, 5];
4583/// let mut result : Vec<&i32> = vec![&data[0]; 3];
4584/// let shared = Rc::new(RefCell::new(result.as_mut_slice()));
4585/// let mut permutator = KPermutationCellIter::new(&data, 3, Rc::clone(&shared));
4586/// let mut counter = 0;
4587/// let timer = Instant::now();
4588///
4589/// permutator.for_each(|_| {
4590/// println!("{}:{:?}", counter, &*shared.borrow());
4591/// counter += 1;
4592/// });
4593///
4594/// println!("Total {} permutations done in {:?}", counter, timer.elapsed());
4595/// assert_eq!(60, counter);
4596/// ```
4597///
4598/// # Notes
4599/// This struct manual iteration performance is about 110% slower than using
4600/// [k-permutation](fn.k_permutation.html) function
4601/// while the slowest using Iterator style is about 2300% slower.
4602/// The additional functionality provided by this struct is that it can be
4603/// pause or completely stop midway while the [k-permutation](fn.k_permutation.html)
4604/// need to be run from start to finish only.
4605///
4606/// # Warning
4607/// This struct implementation use unsafe code.
4608/// This is because inside the `next` function, it require
4609/// a share mutable variable on both the Gosper iterator and
4610/// Heap permutator. It also require to re-assign the
4611/// permutator on first call to `next` which is impossible in current safe Rust.
4612/// To do it in safe Rust way, it need to copy the data
4613/// which will hurt performance.
4614///
4615/// # See
4616/// - [HeapPermutation](struct.HeapPermutationIterator.html)
4617pub struct KPermutationCellIter<'a, T> where T : 'a {
4618 permuted : Rc<RefCell<&'a mut [&'a T]>>,
4619
4620 len : usize,
4621
4622 combinator : LargeCombinationIterator<'a, T>,
4623 permutator : Option<HeapPermutationCellIter<'a, &'a T>>
4624}
4625
4626impl<'a, T> KPermutationCellIter<'a, T> {
4627 pub fn new(data : &'a [T], k : usize, result : Rc<RefCell<&'a mut [&'a T]>>) -> KPermutationCellIter<'a, T> {
4628 let combinator = LargeCombinationIterator::new(data, k);
4629 let n = data.len();
4630
4631 KPermutationCellIter {
4632 permuted : result,
4633
4634 len : divide_factorial(n, n - k),
4635
4636 combinator : combinator,
4637 permutator : None
4638 }
4639 }
4640
4641 /// Consume then return self immediately.
4642 /// It permit functional style operation over iterator
4643 /// from borrow object as Rust isn't yet support
4644 /// `for _ in borrowed_object` directly.
4645 /// It need to be `for _ in borrowed_object.into_iter()`.
4646 pub fn into_iter(self) -> Self {
4647 self
4648 }
4649
4650 /// Get total number of permutation this KPermutationIterator object
4651 /// can permute. It'll be equals to number of possible `next`
4652 /// call.
4653 pub fn len(&self) -> usize {
4654 self.len
4655 }
4656}
4657
4658impl<'a, T> Iterator for KPermutationCellIter<'a, T> {
4659 type Item = ();
4660
4661 fn next(&mut self) -> Option<()> {
4662 let permutator = &mut self.permutator;
4663 let permuted = Rc::clone(&self.permuted);
4664
4665 if let Some(_) = _k_permutation_next_core(
4666 &mut self.combinator,
4667 permutator,
4668 permuted,
4669 #[inline(always)]
4670 |permutator, permuted, comb| {
4671 permuted.borrow_mut().iter_mut().enumerate().for_each(|(i, p)| *p = comb[i]);
4672 if let Some(p) = permutator {
4673 p.reset();
4674 } else {
4675 *permutator = Some(HeapPermutationCellIter::new(permuted));
4676 }
4677 }) {
4678 return Some(());
4679 } else {
4680 return None;
4681 }
4682 }
4683}
4684
4685impl<'a, T> IteratorReset for KPermutationCellIter<'a, T> {
4686 fn reset(&mut self) {
4687 self.combinator.reset();
4688 self.permutator = None;
4689 }
4690}
4691
4692impl<'a, T> ExactSizeIterator for KPermutationCellIter<'a, T> {
4693 fn len(&self) -> usize {
4694 self.len
4695 }
4696}
4697
4698/// k-Permutation over data of length "n" where `k` must be
4699/// less than `n` and store result into mutable pointer.
4700/// It'll attempt to permute given data by pick `k` elements
4701/// out of `n` data. It use Gosper algorithm to pick the elements.
4702/// It then use Heap's algorithm to permute those `k` elements
4703/// and return each permutation back to caller by given
4704/// *mut [&T]>> parameter to
4705/// [new method of KPermutationRefIter](struct.KPermutationRefIter.html#method.new).
4706///
4707/// # Safety
4708/// This object use raw mutable pointer provided from user and keep using it
4709/// in each `next` iteration. Therefore, all raw pointer conditions are applied
4710/// up until this object is dropped.
4711///
4712/// # Rationale
4713/// It uses unsafe to take a mutable pointer to store the result
4714/// to avoid the cost of using Rc<RefCell<>>.
4715/// In uncontroll test environment, this struct perform a complete
4716/// iteration over 8,648,640 permutations in about 66ms where
4717/// [KPermutationCellIter](struct.KPermutationCellIter.html)
4718/// took about 125 ms.
4719/// This function is very much alike
4720/// [unsafe_k_permutation function](fn.unsafe_k_permutation.html)
4721/// but took `Iterator` approach.
4722///
4723/// # Examples
4724/// - Iterator style permit using 'for-in' style loop along with
4725/// enable usage of functional paradigm over iterator object.
4726/// ```
4727/// use permutator::{KPermutationCellIter, IteratorReset};
4728/// use std::cell::RefCell;
4729/// use std::rc::Rc;
4730/// use std::time::Instant;
4731/// let data = [1, 2, 3, 4, 5];
4732/// let mut result : Vec<&i32> = vec![&data[0]; 3];
4733/// let shared = Rc::new(RefCell::new(result.as_mut_slice()));
4734/// let mut permutator = KPermutationCellIter::new(&data, 3, Rc::clone(&shared));
4735/// let mut counter = 0;
4736/// let timer = Instant::now();
4737///
4738/// permutator.for_each(|_| {
4739/// println!("{}:{:?}", counter, &*shared.borrow());
4740/// counter += 1;
4741/// });
4742///
4743/// println!("Total {} permutations done in {:?}", counter, timer.elapsed());
4744/// assert_eq!(60, counter);
4745/// ```
4746///
4747/// # Notes
4748/// This struct manual iteration performance is about 110% slower than using
4749/// [k-permutation](fn.k_permutation.html) function
4750/// while the slowest using Iterator style is about 2300% slower.
4751/// The additional functionality provided by this struct is that it can be
4752/// pause or completely stop midway while the [k-permutation](fn.k_permutation.html)
4753/// need to be run from start to finish only.
4754///
4755/// # See
4756/// - [HeapPermutation](struct.HeapPermutationIterator.html)
4757pub struct KPermutationRefIter<'a, T> where T : 'a {
4758 permuted : *mut [&'a T],
4759
4760 len : usize,
4761
4762 combinator : LargeCombinationIterator<'a, T>,
4763 permutator : Option<HeapPermutationIterator<'a, &'a T>>
4764}
4765
4766impl<'a, T> KPermutationRefIter<'a, T> {
4767 pub unsafe fn new(data : &'a [T], k : usize, result : *mut [&'a T]) -> KPermutationRefIter<'a, T> {
4768 let combinator = LargeCombinationIterator::new(data, k);
4769 let n = data.len();
4770
4771 KPermutationRefIter {
4772 permuted : result,
4773
4774 len : divide_factorial(n, n - k),
4775
4776 combinator : combinator,
4777 permutator : None
4778 }
4779 }
4780
4781 /// Consume then return self immediately.
4782 /// It permit functional style operation over iterator
4783 /// from borrow object as Rust isn't yet support
4784 /// `for _ in borrowed_object` directly.
4785 /// It need to be `for _ in borrowed_object.into_iter()`.
4786 pub fn into_iter(self) -> Self {
4787 self
4788 }
4789
4790 /// Get total number of permutation this KPermutationIterator object
4791 /// can permute. It'll be equals to number of possible `next`
4792 /// call.
4793 pub fn len(&self) -> usize {
4794 self.len
4795 }
4796}
4797
4798impl<'a, T> Iterator for KPermutationRefIter<'a, T> {
4799 type Item = ();
4800
4801 fn next(&mut self) -> Option<()> {
4802 let permutator = &mut self.permutator;
4803 let permuted = self.permuted as *mut [&T];
4804 unsafe {
4805 if let Some(_) = _k_permutation_next_core(
4806 &mut self.combinator,
4807 permutator,
4808 &mut *permuted,
4809 #[inline(always)]
4810 |permutator, permuted, comb| {
4811 permuted.iter_mut().enumerate().for_each(|(i, p)| *p = comb[i]);
4812
4813 if let Some(p) = permutator {
4814 p.reset();
4815 } else {
4816 *permutator = Some(HeapPermutationIterator::new(&mut *permuted));
4817 }
4818 }) {
4819 return Some(());
4820 } else {
4821 return None;
4822 }
4823 }
4824 }
4825}
4826
4827impl<'a, T> IteratorReset for KPermutationRefIter<'a, T> {
4828 fn reset(&mut self) {
4829 self.combinator.reset();
4830 self.permutator = None;
4831 }
4832}
4833
4834impl<'a, T> ExactSizeIterator for KPermutationRefIter<'a, T> {
4835 fn len(&self) -> usize {
4836 self.len
4837 }
4838}
4839
4840/// Core logic for XPermutation
4841///
4842/// # Parameters
4843/// - `a : Vec<usize>` - A vec that contains an index of data currently put into result.
4844/// - `k : usize` - An index of result to be mutated.
4845/// - `l : Vec<usize>` - A vec that contains an index of next data to be put into data.
4846/// - `n : usize` - Total number of data.
4847/// - `p : usize` - An index used for queueing next index or backtrack the traversal.
4848/// - `q : usize` - An index of data to be put into result.
4849/// - `u : Vec<usize>` - A vec cantains an index of data to be put into result when
4850/// algorithm need to be backtracked.
4851/// - `result_fn : FnMut(usize, usize)` - Function that mutate result.
4852/// - `t : FnMut(usize) -> bool` - Function that will be called to check if the branch
4853/// need to be traversed. If it return true, the branch will be traversed. If it return
4854/// false, the current branch will be skip and it'll be backtrack one level.
4855/// The first usize is an index of result to be mutated.
4856/// The second usize is an index of data to be put into result.
4857///
4858/// # Return
4859/// An empty `Option`. When it's `Some`, it means the new result is updated. When it's
4860/// `None`, it means there's no next permutation.
4861fn _x_permutation_next_core(
4862 a : &mut [usize],
4863 k : &mut usize,
4864 l : &mut [usize],
4865 n : usize,
4866 p : &mut usize,
4867 q : &mut usize,
4868 u : &mut [usize],
4869 mut result_fn : impl FnMut(usize, usize),
4870 mut t : impl FnMut(usize) -> bool
4871) -> Option<()>
4872{
4873 /// Return tuple of (p, q) where
4874 /// p = 0 and q = l[0]
4875 #[inline(always)]
4876 fn enter(l : &[usize]) -> (usize, usize) {
4877 return (0, l[0])
4878 }
4879
4880 while *k != 0 {
4881 // "Algo X" X3
4882 // perm[k - 1] = &d[q - 1];
4883 result_fn(*k - 1, *q - 1);
4884 a[*k] = *q;
4885
4886 if t(*k) { // part of "Algo X" X3
4887 if *k == n { // part of "Algo X" X3
4888 loop { // condition of "Algo X" X5
4889 // "Algo X" X6
4890 *k -= 1;
4891
4892 if *k == 0 {
4893 break;
4894 } else {
4895 *p = u[*k];
4896 *q = a[*k];
4897 l[*p] = *q;
4898
4899 // "Algo X" X5
4900 *p = *q;
4901 *q = l[*p];
4902
4903 if *q != 0 {
4904 break;
4905 }
4906 }
4907 }
4908
4909 // visit part of "Algo X" X3
4910 return Some(());
4911 } else {
4912 // "Algo X" X4
4913 u[*k] = *p;
4914 l[*p] = l[*q];
4915 *k += 1;
4916
4917 // "Algo X" X2
4918 let (new_p, new_q) = enter(l);
4919 *p = new_p;
4920 *q = new_q;
4921 }
4922 } else {
4923 // "Algo X" X5
4924 loop {
4925 *p = *q;
4926 *q = l[*p];
4927
4928 if *q != 0 {
4929 break;
4930 }
4931
4932 // "Algo X" X6
4933 *k -= 1;
4934
4935 if *k == 0 {
4936 return None;
4937 } else {
4938 *p = u[*k];
4939 *q = a[*k];
4940 l[*p] = *q;
4941 }
4942 }
4943 }
4944 }
4945
4946 None
4947}
4948
4949/// A lexicographic ordered permutation based on ["Algoritm X" published by
4950/// Donald E. Knuth.](http://www.cs.utsa.edu/~wagner/knuth/fasc2b.pdf) page 20.
4951///
4952/// If order is not important, consider using [heap permutation](struct.HeapPermutationIterator.html)
4953/// struct instead. This struct is a bit slower (about 10%) than [heap
4954/// permutation](struct.HeapPermutationIterator.html) in uncontroll test environment.
4955///
4956/// The algorithm work by simulate tree traversal where some branch can be
4957/// skip altogether. This is archive by provided `t` function that take
4958/// slice of partial result as parameter. If the partial result needed to be skip,
4959/// return false. Otherwise, return true and the algorithm will call this function
4960/// again when the branch is descended deeper. For example: First call to `t` may
4961/// contain [1]. If `t` return true, it will be called again with [1, 2]. If it
4962/// return true, and there's leaf node, cb will be called with [1, 2]. On the other hand,
4963/// if `t` is called with [1, 3] and it return false, it won't call the callback.
4964/// If `t` is called with [4] and it return false, it won't try to traverse deeper even
4965/// if there're [4, 5], or [4, 6]. It will skip altogether and call `t` with [7].
4966/// The process goes on until every branch is traversed.
4967///
4968/// # Example
4969/// Get all lexicalgraphic ordered permutation
4970/// ```Rust
4971/// use permutator::XPermutationIterator;
4972///
4973/// let data = vec![1, 2, 3, 4];
4974/// let mut counter = 0;
4975///
4976/// XPermutationIterator::new(&data, |_| true).for_each(|p| {
4977/// println!("{:?}", p);
4978/// counter += 1;
4979/// });
4980///
4981/// assert_eq!(factorial(data.len()), counter);
4982/// ```
4983/// Skip all permutation that has `1` in first element.
4984/// ```Rust
4985/// use permutator::XPermutationIterator;
4986///
4987/// let data : Vec<u8> = vec![1, 2, 3, 4];
4988/// let mut counter = 0;
4989///
4990/// XPermutationIterator::new(&data, |f| {
4991/// *f[0] != 1u8 // filter all permutation that start with 1
4992/// }).for_each(|p| {
4993/// println!("{:?}", p);
4994/// counter += 1;
4995/// });
4996///
4997/// assert_eq!(factorial(data.len()) - factorial(data.len() - 1), counter);
4998/// ```
4999/// Multi-threads permutation example
5000/// ```Rust
5001/// use permutator::XpermutationIterator;
5002/// use std::time::{Instant};
5003/// let data : Vec<usize> = (0..4).map(|num| num).collect();
5004/// let threads = 2;
5005/// let chunk = data.len() / threads;
5006/// let (tx, rx) = mpsc::channel();
5007///
5008/// for i in 0..threads {
5009/// let start = chunk * i;
5010/// let end = match i {
5011/// j if j == threads - 1 => data.len(), // last thread handle remaining work
5012/// _ => chunk * (i + 1)
5013/// };
5014///
5015/// let l_dat = data.to_owned(); // copy data for each thread
5016/// let end_sig = tx.clone();
5017///
5018/// thread::spawn(move || {
5019/// let timer = Instant::now();
5020///
5021/// let perm = XPermutationIterator::new(
5022/// &l_dat,
5023/// |v| *v[0] >= start && *v[0] < end // skip branch that is outside the start/end
5024/// );
5025///
5026/// let mut counter = 0u64;
5027///
5028/// for p in perm {
5029/// // each permutation is stored in p
5030/// counter += 1;
5031/// }
5032///
5033/// end_sig.send(i).unwrap();
5034/// });
5035/// }
5036///
5037/// let main = thread::spawn(move || { // main thread
5038/// let mut counter = 0;
5039///
5040/// while counter < threads {
5041/// let i = rx.recv().unwrap();
5042/// // do something
5043/// counter += 1;
5044/// }
5045/// });
5046///
5047/// main.join().unwrap();
5048/// ```
5049pub struct XPermutationIterator<'a, F, T>
5050 where F : FnMut(&[&T]) -> bool,
5051 T : 'a
5052{
5053 a : Vec<usize>,
5054 data : &'a [T],
5055 k : usize,
5056 l : Vec<usize>,
5057 len : usize,
5058 n : usize,
5059 p : usize,
5060 q : usize,
5061 result : Vec<&'a T>,
5062 t: F,
5063 u : Vec<usize>,
5064}
5065
5066impl<'a, F, T> XPermutationIterator<'a, F, T>
5067 where F : FnMut(&[&T]) -> bool,
5068 T : 'a
5069{
5070 /// Construct new XPermutationIterator object.
5071 ///
5072 /// # Parameters
5073 /// - `data : &[T]` - A data used for generate permutation.
5074 /// - `t : FnMut(&[&T])` - A function that if return true, will
5075 /// make algorithm continue traversing the tree. Otherwise,
5076 /// the entire branch will be skip.
5077 pub fn new(data : &'a [T], t : F) -> XPermutationIterator<F, T> {
5078 let n = data.len();
5079 let mut l : Vec<usize> = (0..n).map(|k| k + 1).collect();
5080
5081 // l[n] = 0
5082 l.push(0);
5083
5084 // "Algo X" X1 and X2
5085 XPermutationIterator {
5086 a : (0..=n).map(|v| v).collect(),
5087 data : data,
5088 k : 1,
5089 l : l,
5090 len : factorial(n),
5091 n : n,
5092 p : 0,
5093 q : 1,
5094 result : vec![&data[0]; n],
5095 t : t,
5096 u : vec![0; n + 1]
5097 }
5098 }
5099}
5100
5101impl<'a, F, T> Iterator for XPermutationIterator<'a, F, T>
5102 where F : FnMut(&[&T]) -> bool,
5103 T : 'a
5104{
5105 type Item = Vec<&'a T>;
5106
5107 fn next(&mut self) -> Option<Self::Item> {
5108 let data = self.data;
5109 let result = self.result.as_mut_slice();
5110 let result_ptr = &*result as *const [&T];
5111 let t = &mut self.t;
5112 if let Some(_) = _x_permutation_next_core(
5113 &mut self.a,
5114 &mut self.k,
5115 &mut self.l,
5116 self.n,
5117 &mut self.p,
5118 &mut self.q,
5119 &mut self.u,
5120 |k, q| {result[k] = &data[q]},
5121 |k| {
5122 unsafe {
5123 t(&(*result_ptr)[0..k])
5124 }
5125 }) {
5126 Some(result.to_owned())
5127 } else {
5128 None
5129 }
5130 }
5131}
5132
5133impl<'a, F, T> IteratorReset for XPermutationIterator<'a, F, T>
5134 where F : FnMut(&[&T]) -> bool,
5135 T : 'a
5136{
5137 fn reset(&mut self) {
5138 let n = self.data.len();
5139 let mut l : Vec<usize> = (0..n).map(|k| k + 1).collect();
5140
5141 // l[n] = 0
5142 l.push(0);
5143
5144 self.a = (0..=n).map(|v| v).collect();
5145 self.k = 1;
5146 self.l = l;
5147 self.p = 0;
5148 self.q = 1;
5149 self.u = vec![0; n + 1];
5150 }
5151}
5152
5153impl<'a, F, T> ExactSizeIterator for XPermutationIterator<'a, F, T>
5154 where F : FnMut(&[&T]) -> bool,
5155 T : 'a
5156{
5157 fn len(&self) -> usize {
5158 self.len
5159 }
5160}
5161
5162/// A lexicographic ordered permutation based on ["Algoritm X" published by
5163/// Donald E. Knuth.](http://www.cs.utsa.edu/~wagner/knuth/fasc2b.pdf) page 20.
5164///
5165/// If order is not important, consider using [heap permutation](struct.HeapPermutationCellIter.html)
5166/// struct instead. This struct is a bit slower (about 10%) than [heap
5167/// permutation](struct.HeapPermutationCellIter.html) in uncontroll test environment.
5168///
5169/// The algorithm work by simulate tree traversal where some branch can be
5170/// skip altogether. This is archive by provided `t` function that take
5171/// slice of partial result as parameter. If the partial result needed to be skip,
5172/// return false. Otherwise, return true and the algorithm will call this function
5173/// again when the branch is descended deeper. For example: First call to `t` may
5174/// contain [1]. If `t` return true, it will be called again with [1, 2]. If it
5175/// return true, and there's leaf node, cb will be called with [1, 2]. On the other hand,
5176/// if `t` is called with [1, 3] and it return false, it won't call the callback.
5177/// If `t` is called with [4] and it return false, it won't try to traverse deeper even
5178/// if there're [4, 5], or [4, 6]. It will skip altogether and call `t` with [7].
5179/// The process goes on until every branch is traversed.
5180pub struct XPermutationCellIter<'a, F, T>
5181 where F : FnMut(&[&T]) -> bool,
5182 T : 'a
5183{
5184 a : Vec<usize>,
5185 data : &'a [T],
5186 k : usize,
5187 l : Vec<usize>,
5188 len : usize,
5189 n : usize,
5190 p : usize,
5191 q : usize,
5192 result : Rc<RefCell<&'a mut [&'a T]>>,
5193 t: F,
5194 u : Vec<usize>,
5195}
5196
5197impl<'a, F, T> XPermutationCellIter<'a, F, T>
5198 where F : FnMut(&[&T]) -> bool,
5199 T : 'a
5200{
5201 /// Construct new XPermutationIterator object.
5202 ///
5203 /// # Parameters
5204 /// - `data : &[T]` - A data used for generate permutation.
5205 /// - `result : Rc<RefCell<&mut [&T]>>` - A result container.
5206 /// It'll be overwritten on each call to `next`
5207 /// - `t : FnMut(&[&T])` - A function that if return true, will
5208 /// make algorithm continue traversing the tree. Otherwise,
5209 /// the entire branch will be skip.
5210 pub fn new(data : &'a [T], result : Rc<RefCell<&'a mut [&'a T]>>, t : F) -> XPermutationCellIter<'a, F, T> {
5211 let n = data.len();
5212 let mut l : Vec<usize> = (0..n).map(|k| k + 1).collect();
5213
5214 // l[n] = 0
5215 l.push(0);
5216
5217 // "Algo X" X1 and X2
5218 XPermutationCellIter {
5219 a : (0..=n).map(|v| v).collect(),
5220 data : data,
5221 k : 1,
5222 l : l,
5223 len : factorial(n),
5224 n : n,
5225 p : 0,
5226 q : 1,
5227 result : result,
5228 t : t,
5229 u : vec![0; n + 1]
5230 }
5231 }
5232}
5233
5234impl<'a, F, T> Iterator for XPermutationCellIter<'a, F, T>
5235 where F : FnMut(&[&T]) -> bool,
5236 T : 'a
5237{
5238 type Item = ();
5239
5240 fn next(&mut self) -> Option<Self::Item> {
5241 let data = self.data;
5242 let mut result = self.result.borrow_mut();
5243 let result_ptr = (&**result) as *const [&T];
5244 let t = &mut self.t;
5245 if let Some(_) = _x_permutation_next_core(
5246 &mut self.a,
5247 &mut self.k,
5248 &mut self.l,
5249 self.n,
5250 &mut self.p,
5251 &mut self.q,
5252 &mut self.u,
5253 |k, q| {result[k] = &data[q]},
5254 |k| {
5255 unsafe {
5256 t(&(*result_ptr)[0..k])
5257 }
5258 }) {
5259 Some(())
5260 } else {
5261 None
5262 }
5263 }
5264}
5265
5266impl<'a, F, T> IteratorReset for XPermutationCellIter<'a, F, T>
5267 where F : FnMut(&[&T]) -> bool,
5268 T : 'a
5269{
5270 fn reset(&mut self) {
5271 let n = self.data.len();
5272 let mut l : Vec<usize> = (0..n).map(|k| k + 1).collect();
5273
5274 // l[n] = 0
5275 l.push(0);
5276
5277 self.a = (0..=n).map(|v| v).collect();
5278 self.k = 1;
5279 self.l = l;
5280 self.p = 0;
5281 self.q = 1;
5282 self.u = vec![0; n + 1];
5283 }
5284}
5285
5286impl<'a, F, T> ExactSizeIterator for XPermutationCellIter<'a, F, T>
5287 where F : FnMut(&[&T]) -> bool,
5288 T : 'a
5289{
5290 fn len(&self) -> usize {
5291 self.len
5292 }
5293}
5294
5295/// A lexicographic ordered permutation based on ["Algoritm X" published by
5296/// Donald E. Knuth.](http://www.cs.utsa.edu/~wagner/knuth/fasc2b.pdf) page 20.
5297///
5298/// If order is not important, consider using [heap permutation](struct.HeapPermutationRefIter.html)
5299/// struct instead. This struct is a bit slower (about 10%) than [heap
5300/// permutation](struct.HeapPermutationRefIter.html) in uncontroll test environment.
5301///
5302/// The algorithm work by simulate tree traversal where some branch can be
5303/// skip altogether. This is archive by provided `t` function that take
5304/// slice of partial result as parameter. If the partial result needed to be skip,
5305/// return false. Otherwise, return true and the algorithm will call this function
5306/// again when the branch is descended deeper. For example: First call to `t` may
5307/// contain [1]. If `t` return true, it will be called again with [1, 2]. If it
5308/// return true, and there's leaf node, cb will be called with [1, 2]. On the other hand,
5309/// if `t` is called with [1, 3] and it return false, it won't call the callback.
5310/// If `t` is called with [4] and it return false, it won't try to traverse deeper even
5311/// if there're [4, 5], or [4, 6]. It will skip altogether and call `t` with [7].
5312/// The process goes on until every branch is traversed.
5313pub struct XPermutationRefIter<'a, F, T>
5314 where F : FnMut(&[&T]) -> bool,
5315 T : 'a
5316{
5317 a : Vec<usize>,
5318 data : &'a [T],
5319 k : usize,
5320 l : Vec<usize>,
5321 len : usize,
5322 n : usize,
5323 p : usize,
5324 q : usize,
5325 result : &'a mut [&'a T],
5326 t: F,
5327 u : Vec<usize>,
5328}
5329
5330impl<'a, F, T> XPermutationRefIter<'a, F, T>
5331 where F : FnMut(&[&T]) -> bool,
5332 T : 'a
5333{
5334 /// Construct new XPermutationIterator object.
5335 ///
5336 /// # Parameters
5337 /// - `data : &[T]` - A data used for generate permutation.
5338 /// - `result : Rc<RefCell<&mut [&T]>>` - A result container.
5339 /// It'll be overwritten on each call to `next`
5340 /// - `t : FnMut(&[&T])` - A function that if return true, will
5341 /// make algorithm continue traversing the tree. Otherwise,
5342 /// the entire branch will be skip.
5343 pub unsafe fn new(data : &'a [T], result : *mut [&'a T], t : F) -> XPermutationRefIter<'a, F, T> {
5344 let n = data.len();
5345 let mut l : Vec<usize> = (0..n).map(|k| k + 1).collect();
5346
5347 // l[n] = 0
5348 l.push(0);
5349
5350 // "Algo X" X1 and X2
5351 XPermutationRefIter {
5352 a : (0..=n).map(|v| v).collect(),
5353 data : data,
5354 k : 1,
5355 l : l,
5356 len : factorial(n),
5357 n : n,
5358 p : 0,
5359 q : 1,
5360 result : &mut *result,
5361 t : t,
5362 u : vec![0; n + 1]
5363 }
5364 }
5365}
5366
5367impl<'a, F, T> Iterator for XPermutationRefIter<'a, F, T>
5368 where F : FnMut(&[&T]) -> bool,
5369 T : 'a
5370{
5371 type Item = ();
5372
5373 fn next(&mut self) -> Option<Self::Item> {
5374 let data = self.data;
5375 let result = &mut *self.result;
5376 let result_ptr = (&*result) as *const [&T];
5377 let t = &mut self.t;
5378 if let Some(_) = _x_permutation_next_core(
5379 &mut self.a,
5380 &mut self.k,
5381 &mut self.l,
5382 self.n,
5383 &mut self.p,
5384 &mut self.q,
5385 &mut self.u,
5386 |k, q| {result[k] = &data[q]},
5387 |k| {
5388 unsafe {
5389 t(&(*result_ptr)[0..k])
5390 }
5391 }) {
5392 Some(())
5393 } else {
5394 None
5395 }
5396 }
5397}
5398
5399impl<'a, F, T> IteratorReset for XPermutationRefIter<'a, F, T>
5400 where F : FnMut(&[&T]) -> bool,
5401 T : 'a
5402{
5403 fn reset(&mut self) {
5404 let n = self.data.len();
5405 let mut l : Vec<usize> = (0..n).map(|k| k + 1).collect();
5406
5407 // l[n] = 0
5408 l.push(0);
5409
5410 self.a = (0..=n).map(|v| v).collect();
5411 self.k = 1;
5412 self.l = l;
5413 self.p = 0;
5414 self.q = 1;
5415 self.u = vec![0; n + 1];
5416 }
5417}
5418
5419impl<'a, F, T> ExactSizeIterator for XPermutationRefIter<'a, F, T>
5420 where F : FnMut(&[&T]) -> bool,
5421 T : 'a
5422{
5423 fn len(&self) -> usize {
5424 self.len
5425 }
5426}
5427
5428/// Generate a cartesian product on itself in an iterator style.
5429/// The struct implement `Iterator` trait so it can be used in `Iterator`
5430/// style. The struct provide [into_iter()](#method.into_iter()) function
5431/// that return itself.
5432///
5433/// # Example
5434/// ```
5435/// use permutator::SelfCartesianProductIterator;
5436/// use std::time::Instant;
5437/// let data : &[usize] = &[1, 2, 3];
5438/// let n = 3;
5439/// let cart = SelfCartesianProductIterator::new(&data, n);
5440/// let mut counter = 0;
5441/// let timer = Instant::now();
5442///
5443/// for p in cart {
5444/// // println!("{:?}", p);
5445/// counter += 1;
5446/// }
5447///
5448/// // or functional style like the line below
5449/// // cart.into_iter().for_each(|p| {/* do something iterative style */});
5450///
5451/// assert_eq!(data.len().pow(n as u32), counter);
5452/// println!("Total {} products done in {:?}", counter, timer.elapsed());
5453/// ```
5454pub struct SelfCartesianProductIterator<'a, T> where T : 'a {
5455 c : Vec<usize>,
5456 domain : &'a [T],
5457 exhausted : bool,
5458 i : usize,
5459 n : usize,
5460
5461 result : Vec<&'a T>
5462}
5463
5464impl<'a, T> SelfCartesianProductIterator<'a, T> where T : 'a {
5465 /// Create a new Cartesian product iterator that create a product on
5466 /// itself `n` times.
5467 /// # Parameters
5468 /// - `domain` A slice of domains to create a cartesian product between
5469 /// each domain inside it.
5470 /// - `n` the size of product. For example `n = 3` means create
5471 /// a cartesian product over `domain` paremeter 3 times.
5472 /// This is equals to create a `domains` contains
5473 /// cloned `domain` 3 time.
5474 /// # Return
5475 /// An object that can be iterate over in iterator style.
5476 pub fn new(domain : &'a[T], n : usize) -> SelfCartesianProductIterator<'a, T> {
5477
5478 SelfCartesianProductIterator {
5479 c : vec![0; n],
5480 domain : domain,
5481 exhausted : false,
5482 i : 0,
5483 n : n,
5484
5485 result : vec![&domain[0]; n]
5486 }
5487 }
5488
5489 /// Consume itself and return without modify it.
5490 /// Typical usecase is `for p in ref_to_this.into_iter() {}`
5491 /// or `ref_to_this.into_iter().for_each(|p| {/* Do something with product */});`
5492 pub fn into_iter(self) -> Self {
5493 self
5494 }
5495}
5496
5497impl<'a, T> Iterator for SelfCartesianProductIterator<'a, T> {
5498 type Item = Vec<&'a T>;
5499
5500 /// Each iteration return a new Vec contains borrowed element inside
5501 /// an Option. The result can be collected by using `collect` method
5502 /// from `Iterator` trait.
5503 ///
5504 /// Return None when exhausted.
5505 fn next(&mut self) -> Option<Vec<&'a T>> {
5506 let result = &mut self.result;
5507 let domain = self.domain;
5508 _cartesian_next_core(
5509 &mut self.i,
5510 &mut self.c,
5511 &mut self.exhausted,
5512 self.n,
5513 #[inline(always)]
5514 |_| {
5515 domain.len()
5516 },
5517 #[inline(always)]
5518 |i, j| {
5519 result[i] = &domain[j];
5520 }
5521 );
5522
5523 if self.exhausted {
5524 None
5525 } else {
5526 self.i -= 1; // rewind `i` back to last domain
5527 Some(result.to_owned())
5528 }
5529 }
5530}
5531
5532impl<'a, T> IteratorReset for SelfCartesianProductIterator<'a, T> {
5533 fn reset(&mut self) {
5534 self.c = vec![0; self.n];
5535 self.exhausted = false;
5536 self.i = 0;
5537 }
5538}
5539
5540impl<'a, T> ExactSizeIterator for SelfCartesianProductIterator<'a, T> {
5541 fn len(&self) -> usize {
5542 self.n
5543 }
5544}
5545
5546/// Generate a cartesian product on itself in an iterator style.
5547/// The struct implement `Iterator` trait so it can be used in `Iterator`
5548/// style. The struct provide [into_iter()](#method.into_iter()) function
5549/// that return itself.
5550///
5551/// # Example
5552/// ```
5553/// use permutator::SelfCartesianProductCellIter;
5554/// use std::cell::RefCell;
5555/// use std::rc::Rc;
5556/// use std::time::Instant;
5557/// let data : &[usize] = &[1, 2, 3];
5558/// let n = 3;
5559/// let result : &mut[&usize] = &mut vec![&data[0]; n];
5560/// let shared = Rc::new(RefCell::new(result));
5561/// let cart = SelfCartesianProductCellIter::new(&data, n, Rc::clone(&shared));
5562/// let mut counter = 0;
5563/// let timer = Instant::now();
5564///
5565/// for _ in cart {
5566/// // println!("{:?}", &*shared.borrow());
5567/// counter += 1;
5568/// }
5569///
5570/// // or functional style like the line below
5571/// // cart.into_iter().for_each(|_| {/* do something iterative style */});
5572///
5573/// assert_eq!(data.len().pow(n as u32), counter);
5574/// println!("Total {} products done in {:?}", counter, timer.elapsed());
5575/// ```
5576pub struct SelfCartesianProductCellIter<'a, T> where T : 'a {
5577 c : Vec<usize>,
5578 domain : &'a [T],
5579 exhausted : bool,
5580 i : usize,
5581 n : usize,
5582
5583 result : Rc<RefCell<&'a mut [&'a T]>>
5584}
5585
5586impl<'a, T> SelfCartesianProductCellIter<'a, T> where T : 'a {
5587 /// Create a new Cartesian product iterator that create a product on
5588 /// itself `n` times.
5589 /// # Parameters
5590 /// - `domain` A slice of domains to create a cartesian product between
5591 /// each domain inside it.
5592 /// This is equals to create a `domains` contains
5593 /// cloned `domain` 3 time.
5594 /// - `n` the size of product. For example `n = 3` means create
5595 /// a cartesian product over `domain` paremeter 3 times.
5596 /// - `result` an Rc<RefCell<&mut[&T]>> to store each product
5597 /// # Return
5598 /// An object that can be iterate over in iterator style.
5599 pub fn new(domain : &'a[T], n : usize, result : Rc<RefCell<&'a mut [&'a T]>>) -> SelfCartesianProductCellIter<'a, T> {
5600
5601 SelfCartesianProductCellIter {
5602 c : vec![0; n],
5603 domain : domain,
5604 exhausted : false,
5605 i : 0,
5606 n : n,
5607
5608 result : Rc::clone(&result)
5609 }
5610 }
5611
5612 /// Consume itself and return without modify it.
5613 /// Typical usecase is `for p in ref_to_this.into_iter() {}`
5614 /// or `ref_to_this.into_iter().for_each(|p| {/* Do something with product */});`
5615 pub fn into_iter(self) -> Self {
5616 self
5617 }
5618}
5619
5620impl<'a, T> Iterator for SelfCartesianProductCellIter<'a, T> {
5621 type Item = ();
5622
5623 /// Each iteration return a new Vec contains borrowed element inside
5624 /// an Option. The result can be collected by using `collect` method
5625 /// from `Iterator` trait.
5626 ///
5627 /// Return None when exhausted.
5628 fn next(&mut self) -> Option<()> {
5629 let mut result = self.result.borrow_mut();
5630 let domain = self.domain;
5631 _cartesian_next_core(
5632 &mut self.i,
5633 &mut self.c,
5634 &mut self.exhausted,
5635 self.n,
5636 #[inline(always)]
5637 |_| {
5638 domain.len()
5639 },
5640 #[inline(always)]
5641 |i, j| {
5642 result[i] = &domain[j];
5643 }
5644 );
5645
5646 if self.exhausted {
5647 None
5648 } else {
5649 self.i -= 1; // rewind `i` back to last domain
5650 Some(())
5651 }
5652 }
5653}
5654
5655impl<'a, T> IteratorReset for SelfCartesianProductCellIter<'a, T> {
5656 fn reset(&mut self) {
5657 self.c = vec![0; self.n];
5658 self.exhausted = false;
5659 self.i = 0;
5660 }
5661}
5662
5663impl<'a, T> ExactSizeIterator for SelfCartesianProductCellIter<'a, T> {
5664 fn len(&self) -> usize {
5665 self.n
5666 }
5667}
5668
5669/// Generate a cartesian product on itself in an iterator style.
5670/// The struct implement `Iterator` trait so it can be used in `Iterator`
5671/// style. The struct provide [into_iter()](#method.into_iter()) function
5672/// that return itself.
5673///
5674/// # Example
5675/// ```
5676/// use permutator::SelfCartesianProductRefIter;
5677/// use std::time::Instant;
5678/// let data : &[usize] = &[1, 2, 3];
5679/// let n = 3;
5680/// let result : &mut[&usize] = &mut vec![&data[0]; n];
5681/// let shared = result as *mut[&usize];
5682///
5683/// unsafe {
5684/// let cart = SelfCartesianProductRefIter::new(&data, n, result);
5685/// let mut counter = 0;
5686/// let timer = Instant::now();
5687///
5688/// for _ in cart {
5689/// // println!("{:?}", &*shared);
5690/// counter += 1;
5691/// }
5692///
5693/// // or functional style like the line below
5694/// // cart.into_iter().for_each(|_| {/* do something iterative style */});
5695///
5696/// assert_eq!(data.len().pow(n as u32), counter);
5697/// println!("Total {} products done in {:?}", counter, timer.elapsed());
5698/// }
5699/// ```
5700pub struct SelfCartesianProductRefIter<'a, T> where T : 'a {
5701 c : Vec<usize>,
5702 domain : &'a [T],
5703 exhausted : bool,
5704 i : usize,
5705 n : usize,
5706
5707 result : &'a mut [&'a T]
5708}
5709
5710impl<'a, T> SelfCartesianProductRefIter<'a, T> where T : 'a {
5711 /// Create a new Cartesian product iterator that create a product on
5712 /// itself `n` times.
5713 /// # Parameters
5714 /// - `domain` A slice of domains to create a cartesian product between
5715 /// each domain inside it.
5716 /// This is equals to create a `domains` contains
5717 /// cloned `domain` 3 time.
5718 /// - `n` the size of product. For example `n = 3` means create
5719 /// a cartesian product over `domain` paremeter 3 times.
5720 /// - `result` *mut[&T] to store each product
5721 /// # Return
5722 /// An object that can be iterate over in iterator style.
5723 pub unsafe fn new(domain : &'a[T], n : usize, result : * mut [&'a T]) -> SelfCartesianProductRefIter<'a, T> {
5724
5725 SelfCartesianProductRefIter {
5726 c : vec![0; n],
5727 domain : domain,
5728 exhausted : false,
5729 i : 0,
5730 n : n,
5731
5732 result : &mut *result
5733 }
5734 }
5735
5736 /// Consume itself and return without modify it.
5737 /// Typical usecase is `for p in ref_to_this.into_iter() {}`
5738 /// or `ref_to_this.into_iter().for_each(|p| {/* Do something with product */});`
5739 pub fn into_iter(self) -> Self {
5740 self
5741 }
5742}
5743
5744impl<'a, T> Iterator for SelfCartesianProductRefIter<'a, T> {
5745 type Item = ();
5746
5747 /// Each iteration return a new Vec contains borrowed element inside
5748 /// an Option. The result can be collected by using `collect` method
5749 /// from `Iterator` trait.
5750 ///
5751 /// Return None when exhausted.
5752 fn next(&mut self) -> Option<()> {
5753 let result = &mut self.result;
5754 let domain = self.domain;
5755 _cartesian_next_core(
5756 &mut self.i,
5757 &mut self.c,
5758 &mut self.exhausted,
5759 self.n,
5760 #[inline(always)]
5761 |_| {
5762 domain.len()
5763 },
5764 #[inline(always)]
5765 |i, j| {
5766 result[i] = &domain[j];
5767 }
5768 );
5769
5770 if self.exhausted {
5771 None
5772 } else {
5773 self.i -= 1; // rewind `i` back to last domain
5774 Some(())
5775 }
5776 }
5777}
5778
5779impl<'a, T> IteratorReset for SelfCartesianProductRefIter<'a, T> {
5780 fn reset(&mut self) {
5781 self.c = vec![0; self.n];
5782 self.exhausted = false;
5783 self.i = 0;
5784 }
5785}
5786
5787impl<'a, T> ExactSizeIterator for SelfCartesianProductRefIter<'a, T> {
5788 fn len(&self) -> usize {
5789 self.n
5790 }
5791}
5792
5793/// Create a cartesian product out of `T`.
5794/// For example,
5795/// - `T` can be a slice of slices so the product can
5796/// be created between all the slices.
5797/// - `T` can be a pair of slice to slices and Rc<RefCell<>> contains
5798/// a mutable product from slices.
5799///
5800/// # Examples
5801/// - Create a cartesian product and return it as new owned value
5802/// ```
5803/// use std::time::Instant;
5804/// use permutator::CartesianProduct;
5805///
5806/// let mut counter = 0;
5807/// let timer = Instant::now();
5808/// let data : &[&[u8]]= &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
5809///
5810/// data.cart_prod().for_each(|p| {
5811/// counter += 1;
5812/// });
5813///
5814/// assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
5815/// println!("Total {} products done in {:?}", counter, timer.elapsed());
5816/// ```
5817/// - Create a cartesian product and return result inside
5818/// Rc<RefCell<>>
5819/// ```
5820/// use std::cell::RefCell;
5821/// use std::rc::Rc;
5822/// use std::time::Instant;
5823/// use permutator::CartesianProduct;
5824///
5825/// let mut counter = 0;
5826/// let timer = Instant::now();
5827/// let data : &[&[u8]]= &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
5828/// let mut result = vec![&data[0][0]; data.len()];
5829/// let shared = Rc::new(RefCell::new(result.as_mut_slice()));
5830///
5831/// (data, Rc::clone(&shared)).cart_prod().for_each(|_| {
5832/// counter += 1;
5833/// });
5834///
5835/// assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
5836/// println!("Total {} products done in {:?}", counter, timer.elapsed());
5837/// ```
5838pub trait CartesianProduct<'a> {
5839 type Producer : Iterator;
5840
5841 /// Create a cartesian product producer which
5842 /// can be used to iterate over each product.
5843 fn cart_prod(&'a self) -> Self::Producer;
5844}
5845
5846impl<'a, T> CartesianProduct<'a> for [&'a [T]]
5847 where T : 'a {
5848
5849 type Producer = CartesianProductIterator<'a, T>;
5850
5851 fn cart_prod(&'a self) -> Self::Producer {
5852 CartesianProductIterator::new(self)
5853 }
5854}
5855
5856impl<'a, T> CartesianProduct<'a> for Vec<&'a [T]>
5857 where T : 'a {
5858
5859 type Producer = CartesianProductIterator<'a, T>;
5860
5861 fn cart_prod(&'a self) -> Self::Producer {
5862 CartesianProductIterator::new(self)
5863 }
5864}
5865
5866/// A type that represent a cartesian product of the slice
5867/// over slices and return result into Rc<RefCell<&mut [&T]>>
5868/// by using [CartesianProductCellIter](trait.CartesianProductCellIter.html)
5869///
5870/// # Format
5871/// 1. A mutable slice of slices.
5872/// It's a domains to of a cartesian product operation.
5873/// 2. An Rc<RefCell<&mut[&T]>.
5874/// It's a result container.
5875pub type CartesianProductIntoCellParams<'a, T> = (&'a [&'a [T]], Rc<RefCell<&'a mut[&'a T]>>);
5876
5877impl<'a, 'b: 'a, T> CartesianProduct<'a> for CartesianProductIntoCellParams<'b, T>
5878 where T : 'b {
5879
5880 type Producer = CartesianProductCellIter<'b, T>;
5881
5882 fn cart_prod(&'a self) -> Self::Producer {
5883 CartesianProductCellIter::new(self.0, Rc::clone(&self.1))
5884 }
5885}
5886
5887/// A type that used exclusively for [trait CartesianProduct](trait.CartesianProduct.html).
5888/// It return [CartesianProductRefIter](struct.CartesianProductRefIter.html).
5889///
5890/// It's a tuple where first element is a slice contains slices represents a domains
5891/// of Cartesian product function. The second element is a mutable pointer to a slice which
5892/// will be used to store each product.
5893///
5894/// # Format
5895/// 1. A mutable slice of slices.
5896/// It's a domains to of a cartesian product operation.
5897/// 2. A pointer to mutable slice of borrowed value.
5898/// It's a result container.
5899pub type CartesianProductIntoRefParams<'a, T> = (&'a [&'a [T]], *mut [&'a T]);
5900
5901/// An implementation for convenient use of [CartesianProductRefIter](struct.CartesianProductRefIter.html)
5902/// # Warning
5903/// It hid unsafe object instantiation of [CartesianProductRefIter](struct.CartesianProductRefIter.html#method.new)
5904/// from user but all unsafe conditions are still applied as long as
5905/// the the life of object itself.
5906///
5907impl<'a, 'b: 'a, T> CartesianProduct<'a> for CartesianProductIntoRefParams<'b, T>
5908 where T : 'b {
5909
5910 type Producer = CartesianProductRefIter<'b, T>;
5911
5912 fn cart_prod(&'a self) -> Self::Producer {
5913 unsafe {
5914 CartesianProductRefIter::new(self.0, self.1)
5915 }
5916 }
5917}
5918
5919/// A type that used exclusively for [trait CartesianProduct](trait.CartesianProduct.html).
5920/// It return [SelfCartesianProductIterator](struct.SelfCartesianProductIterator.html).
5921///
5922/// # Format
5923/// 1. A slice of T.
5924/// 2. How many time to create a product on slice
5925pub type SelfCartesianProduct<'a, T> = (&'a [T], usize);
5926
5927impl<'a, 'b : 'a, T> CartesianProduct<'a> for SelfCartesianProduct<'b, T>
5928 where T : 'b {
5929 type Producer = SelfCartesianProductIterator<'b, T>;
5930
5931 fn cart_prod(&'a self) -> Self::Producer {
5932 SelfCartesianProductIterator::new(self.0, self.1)
5933 }
5934}
5935
5936/// A type that used exclusively for [trait CartesianProduct](trait.CartesianProduct.html).
5937/// It return [SelfCartesianProductCellIter](struct.SelfCartesianProductCellIter.html).
5938///
5939/// # Format
5940/// 1. A slice of T.
5941/// 2. How many time to create a product on slice
5942/// 3. An Rc<RefCell<&mut [T]>> to store each product on each iteration.
5943pub type SelfCartesianProductIntoCellParams<'a, T> = (&'a [T], usize, Rc<RefCell<&'a mut [&'a T]>>);
5944
5945impl<'a, 'b : 'a, T> CartesianProduct<'a> for SelfCartesianProductIntoCellParams<'b, T>
5946 where T : 'b {
5947 type Producer = SelfCartesianProductCellIter<'b, T>;
5948
5949 fn cart_prod(&'a self) -> Self::Producer {
5950 SelfCartesianProductCellIter::new(self.0, self.1, Rc::clone(&self.2))
5951 }
5952}
5953
5954/// A type that used exclusively for [trait CartesianProduct](trait.CartesianProduct.html).
5955/// It return [SelfCartesianProductRefIter](struct.SelfCartesianProductRefIter.html).
5956///
5957/// # Format
5958/// 1. A slice of T.
5959/// 2. How many time to create a product on slice
5960/// 3. A mutable pointer to a slice of ref T
5961pub type SelfCartesianProductIntoRefParams<'a, T> = (&'a [T], usize, *mut [&'a T]);
5962
5963/// An implementation for convenient use of [SelfCartesianProductRefIter](struct.SelfCartesianProductRefIter.html)
5964/// # Warning
5965/// It hid unsafe object instantiation of [SelfCartesianProductRefIter](struct.SelfCartesianProductRefIter.html#method.new)
5966/// from user but all unsafe conditions are still applied as long as
5967/// the life of object itself.
5968impl<'a, 'b : 'a, T> CartesianProduct<'a> for SelfCartesianProductIntoRefParams<'b, T>
5969 where T : 'b {
5970 type Producer = SelfCartesianProductRefIter<'b, T>;
5971
5972 fn cart_prod(&'a self) -> Self::Producer {
5973 unsafe {
5974 SelfCartesianProductRefIter::new(self.0, self.1, self.2)
5975 }
5976 }
5977}
5978
5979/// Create a combination out of `T`
5980/// Normally, it take a `[T]` or `Vec<T>` to create a combination.
5981///
5982/// # Example
5983/// ```
5984/// use permutator::Combination;
5985/// let data = [1, 2, 3, 4, 5];
5986/// data.combination(3).for_each(|c| {
5987/// // called multiple times.
5988/// // Each call have [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]
5989/// // [1, 2, 5], [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5],
5990/// // and [3, 4, 5] respectively.
5991/// println!("{:?}", c);
5992/// });
5993/// ```
5994///
5995/// See [Example implementation](trait.Combination.html#foreign-impls) on
5996/// foreign type.
5997pub trait Combination<'a> {
5998 type Combinator : Iterator;
5999
6000 /// Create a family of [LargeCombinationIterator](struct.LargeCombinationIterator.html)
6001 /// of `k` size out of `self`.
6002 /// See [LargeCombinationIterator](struct.LargeCombinationIterator.html) for
6003 /// how to use [LargeCombinationIterator](struct.LargeCombinationIterator.html)
6004 ///
6005 /// # Return
6006 /// A new family of [LargeCombinationIterator<T>](struct.LargeCombinationIterator.html)
6007 fn combination(&'a self, k : usize) -> Self::Combinator;
6008}
6009
6010/// An implementation for convenient use of [LargeCombinationIterator](struct.LargeCombinationIterator.html)
6011impl<'a, T> Combination<'a> for [T] where T : 'a {
6012 type Combinator = LargeCombinationIterator<'a, T>;
6013
6014 fn combination(&'a self, k : usize) -> LargeCombinationIterator<'a, T> {
6015
6016 LargeCombinationIterator::new(self, k)
6017 }
6018}
6019
6020/// An implementation for convenient use of [LargeCombinationIterator](struct.LargeCombinationIterator.html)
6021impl<'a, T> Combination<'a> for Vec<T> where T : 'a {
6022 type Combinator = LargeCombinationIterator<'a, T>;
6023
6024 fn combination(&'a self, k : usize) -> LargeCombinationIterator<'a, T> {
6025
6026 LargeCombinationIterator::new(self, k)
6027 }
6028}
6029
6030/// A pair of source and sink to get a sharable combination.
6031///
6032/// It's tuple contains a source data to generate a combination
6033/// and a sink to temporary store each combination.
6034///
6035/// This type is use exclusively with [trait Combination](trait.Combination.html#implementors)
6036///
6037/// # Format
6038/// 1. First value in tuple is a `&'a [T]` -
6039/// It's a source data to generate a combination.
6040/// 2. Second value in tuple is an Rc<RefCell<&'a mut[&'a T]>>` -
6041/// It's a sink to temporary store each combination.
6042pub type CombinationIntoCellParams<'a, T> = (&'a [T], Rc<RefCell<&'a mut[&'a T]>>);
6043
6044/// An implementation for convenient use of [LargeCombinationCellIter](struct.LargeCombinationCellIter.html)
6045impl<'a, 'b : 'a, T> Combination<'a> for CombinationIntoCellParams<'b, T> {
6046 type Combinator = LargeCombinationCellIter<'b, T>;
6047
6048 fn combination(&'a self, k : usize) -> LargeCombinationCellIter<'b, T> {
6049 LargeCombinationCellIter::new(self.0, k, Rc::clone(&self.1))
6050 }
6051}
6052
6053/// A pair of source and sink to get a sharable combination.
6054///
6055/// It's tuple contains a source data to generate a combination
6056/// and a sink to temporary store each combination.
6057///
6058/// This type is use exclusively with [trait Combination](trait.Combination.html#implementors)
6059///
6060/// # Format
6061/// 1. A mutable slice of slices.
6062/// It's a domains to of a cartesian product operation.
6063/// 2. A pointer to mutable slice of borrowed value.
6064/// It's a result container.
6065pub type CombinationIntoRefParams<'a, T> = (&'a [T], * mut[&'a T]);
6066
6067/// An implementation for convenient use of [LargeCombinationRefIter](struct.LargeCombinationRefIter.html)
6068/// # Warning
6069/// It hid unsafe object instantiation of [LargeCombinationRefIter](struct.LargeCombinationRefIter.html#method.new)
6070/// from user but all unsafe conditions are still applied as long as
6071/// the life of object itself.
6072impl<'a, 'b : 'a, T> Combination<'a> for CombinationIntoRefParams<'b, T> {
6073 type Combinator = LargeCombinationRefIter<'b, T>;
6074
6075 fn combination(&'a self, k : usize) -> LargeCombinationRefIter<'b, T> {
6076 unsafe {
6077 LargeCombinationRefIter::new(self.0, k, self.1)
6078 }
6079 }
6080}
6081
6082/// Create a permutation iterator that permute data in place.
6083/// Built-in implementation return an object of
6084/// [HeapPermutation](struct.HeapPermutationIterator.html) for slice/array and Vec.
6085/// It return an object of [HeapPermutationCellIter](struct.HeapPermutationCellIter.html)
6086/// on data type of `Rc<RefCell<&mut [T]>>`.
6087///
6088/// # Example
6089/// For typical permutation:
6090/// ```
6091/// use permutator::Permutation;
6092/// let mut data = vec![1, 2, 3];
6093/// data.permutation().for_each(|p| {
6094/// // call multiple times. It'll print [1, 2, 3], [2, 1, 3], [3, 1, 2],
6095/// // [1, 3, 2], [2, 3, 1], and [3, 2, 1] respectively.
6096/// println!("{:?}", p);
6097/// });
6098/// ```
6099/// For k-permutation:
6100/// ```
6101/// use permutator::{Combination, Permutation};
6102/// let data = [1, 2, 3, 4, 5];
6103/// let k = 3;
6104///
6105/// data.combination(k).for_each(|mut combination| {
6106/// // print the first combination
6107/// combination.permutation().for_each(|permuted| {
6108/// // print permutation of each combination
6109/// println!("{:?}", permuted);
6110/// });
6111/// });
6112/// // All k-permutation printed
6113/// ```
6114///
6115/// # See
6116/// - [HeapPermutation](struct.HeapPermutationIterator.html) for more detail
6117/// about how to use [HeapPermutation](struct.HeapPermutationIterator.html).
6118/// - [HeapPermutationCellIter](struct.HeapPermutationCellIter.html) for more detail
6119/// about how to use [HeapPermutationCellIter](struct.HeapPermutationCellIter.html)
6120/// - [Example implementation](trait.Permutation.html#foreign-impls) on foreign type
6121///
6122/// # Breaking change from 0.3.x to 0.4
6123/// Since version 0.4.0, the first result return by this iterator
6124/// will be the original value
6125pub trait Permutation<'a> {
6126 /// A permutation generator for a collection of data.
6127 /// # See
6128 /// - [Foreign implementation for an example different return type](trait.Permutation.html#foreign-impls)
6129 type Permutator : Iterator;
6130
6131 /// Create a permutation based on Heap's algorithm.
6132 /// It return [HeapPermutation](struct.HeapPermutationIterator.html) object.
6133 fn permutation(&'a mut self) -> Self::Permutator;
6134}
6135
6136/// Generate permutation on an array or slice of T
6137/// It return mostly similar to [HeapPermutation](struct.HeapPermutationIterator.html)
6138/// but it include an original value as first value return by `Iterator`.
6139///
6140/// # Breaking change from 0.3.x to 0.4
6141/// Since version 0.4.0, the first result return by this iterator
6142/// will be the original value
6143impl<'a, T> Permutation<'a> for [T] where T : 'a + Clone {
6144 /// Use [HeapPermutation](struct.HeapPermutationIterator.html)
6145 /// as permutation generator
6146 type Permutator = Chain<Once<Vec<T>>, HeapPermutationIterator<'a, T>>;
6147
6148 fn permutation(&'a mut self) -> Chain<Once<Vec<T>>, HeapPermutationIterator<T>> {
6149 let origin = once(self.to_owned());
6150 origin.into_iter().chain(HeapPermutationIterator::new(self))
6151 }
6152}
6153
6154/// Generate permutation on a Vec of T
6155/// It return mostly similar to [HeapPermutation](struct.HeapPermutationIterator.html)
6156/// but it include an original value as first value return by `Iterator`.
6157///
6158/// # Breaking change from 0.3.x to 0.4
6159/// Since version 0.4.0, the first result return by this iterator
6160/// will be the original value
6161impl<'a, T> Permutation<'a> for Vec<T> where T : 'a + Clone {
6162 /// Use [HeapPermutation](struct.HeapPermutationIterator.html)
6163 /// as permutation generator
6164 type Permutator = Chain<Once<Vec<T>>, HeapPermutationIterator<'a, T>>;
6165
6166 fn permutation(&'a mut self) -> Chain<Once<Vec<T>>, HeapPermutationIterator<T>> {
6167 let origin = once(self.to_owned());
6168 origin.into_iter().chain(HeapPermutationIterator::new(self))
6169 }
6170}
6171
6172/// Generate a sharable permutation inside `Rc<RefCell<&mut [T]>>`
6173/// It return [HeapPermutationCellIter](struct.HeapPermutationCellIter.html)
6174/// but it include an original value as first value return by `Iterator`.
6175///
6176/// # Breaking change from 0.3.x to 0.4
6177/// Since version 0.4.0, the first result return by this iterator
6178/// will be the original value
6179impl<'a, T> Permutation<'a> for Rc<RefCell<&'a mut[T]>> where T :'a {
6180 /// Use [HeapPermutationCellIter](struct.HeapPermutationCellIter.html)
6181 /// as permutation generator
6182 type Permutator = Chain<Once<()>, HeapPermutationCellIter<'a, T>>;
6183
6184 fn permutation(&'a mut self) -> Chain<Once<()>, HeapPermutationCellIter<T>> {
6185 let original = once(());
6186 original.into_iter().chain(
6187 HeapPermutationCellIter {
6188 c : vec![0; self.borrow().len()],
6189 data : Rc::clone(self),
6190 i : 0
6191 }
6192 )
6193 }
6194}
6195
6196/// Generate permutation a mutable pointer to slice of T
6197/// It return [HeapPermutation](struct.HeapPermutationRefIter.html)
6198/// but it include an original value as first value return by `Iterator`.
6199///
6200/// # Warning
6201/// This implementation hid unsafe inside the permutation function but
6202/// doesn't provide any additional safety.
6203/// User need to treat the return object as unsafe.
6204///
6205/// # Breaking change from 0.3.x to 0.4
6206/// Since version 0.4.0, the first result return by this iterator
6207/// will be the original value
6208impl<'a, T> Permutation<'a> for *mut [T] where T : 'a + Clone {
6209 /// Use [HeapPermutation](struct.HeapPermutationIterator.html)
6210 /// as permutation generator
6211 type Permutator = Chain<Once<()>, HeapPermutationRefIter<'a, T>>;
6212
6213 fn permutation(&'a mut self) -> Chain<Once<()>, HeapPermutationRefIter<T>> {
6214 let original = once(());
6215 unsafe {
6216 original.into_iter().chain(
6217 HeapPermutationRefIter {
6218 c : vec![0; (**self).len()],
6219 data : &mut (**self),
6220 i : 0
6221 }
6222 )
6223 }
6224 }
6225}
6226
6227/// A pair of parameter that allow `Permutation` trait
6228/// to create [k-permutation iterator](struct.KPermutationIterator.html) from it.
6229///
6230/// This type is used exclusively in [trait Permutation](trait.Permutation.html#implementors)
6231///
6232/// # Format
6233/// 1. First value in tuple is `&'a [T]`.
6234/// It's a source data to generate k-permutation.
6235/// 2. Second value in tuple is `usize`.
6236/// It's `k` size which shall be less than `n`
6237/// where `n` is a length of the first value.
6238pub type KPermutationParams<'a, T> = (&'a [T], usize);
6239
6240impl<'a, T> Permutation<'a> for KPermutationParams<'a, T> {
6241 type Permutator = KPermutationIterator<'a, T>;
6242
6243 fn permutation(&'a mut self) -> KPermutationIterator<'a, T> {
6244 KPermutationIterator::new(self.0, self.1)
6245 }
6246}
6247
6248/// A tuples of 3 parameters that allow `Permutation` trait
6249/// to create [k-permutation iterator](struct.KPermutationCellIter.html) from it.
6250///
6251/// This type is used exclusively in [trait Permutation](trait.Permutation.html#implementors)
6252///
6253/// # Format
6254/// 1. First value in tuple is `&'a [T]`.
6255/// It's a source data to generate k-permutation.
6256/// 2. Second value in tuple is `usize`.
6257/// It's `k` size which shall be less than `n`
6258/// where `n` is a length of the first value.
6259/// 3. Third value in tuple is `Rc<RefCell<&mut[&T]>>`
6260/// It's a sink of operation. It's a ref to each permutation result.
6261pub type KPermutationIntoCellParams<'a, T> = (&'a [T], usize, Rc<RefCell<&'a mut [&'a T]>>);
6262
6263impl<'a, 'b : 'a, T> Permutation<'a> for KPermutationIntoCellParams<'b, T> {
6264 type Permutator = KPermutationCellIter<'b, T>;
6265
6266 fn permutation(&'a mut self) -> Self::Permutator {
6267 KPermutationCellIter::new(self.0, self.1, Rc::clone(&self.2))
6268 }
6269}
6270
6271/// A tuple of 3 parameters that allow `Permutation` trait
6272/// to create [k-permutation ref iterator](struct.KPermutationRefIterator.html) from it.
6273///
6274/// This type is used exclusively in [trait Permutation](trait.Permutation.html#implementors)
6275///
6276/// # Format
6277/// 1. First value in tuple is `&'a [T]`.
6278/// It's a source data to generate k-permutation.
6279/// 2. Second value in tuple is `usize`.
6280/// It's `k` size which shall be less than `n`
6281/// where `n` is a length of the first value.
6282/// 3. Third value in tule i `*mut [&T]`
6283/// It's a sink that store a ref to each permutation.
6284pub type KPermutationIntoRefParams<'a, T> = (&'a [T], usize, *mut [&'a T]);
6285
6286impl<'a, 'b : 'a, T> Permutation<'a> for KPermutationIntoRefParams<'b, T> {
6287 type Permutator = KPermutationRefIter<'b, T>;
6288
6289 fn permutation(&'a mut self) -> Self::Permutator {
6290 unsafe {
6291 KPermutationRefIter::new(self.0, self.1, &mut *self.2)
6292 }
6293 }
6294}
6295
6296// if GAT is supported by Rust. This is probably how Lex-ordered permutation trait
6297// should look like.
6298//
6299// struct LexicographicallyOrdered;
6300//
6301// impl<'a, 'b : 'a, T> Permutation<'a> for (&'b [T], LexicographicallyOrdered)
6302// {
6303// type Permutator<F> = XPermutationIterator<'a, F, T>;
6304//
6305// fn permutation(&'a mut self) -> Self::Permutator {
6306// let (d, ..) = self;
6307// XPermutationIterator::new(d, |_| true)
6308// }
6309// }
6310
6311/// # Deprecated
6312/// Superseded by algorithm published by Stanford university
6313/// Generate binary representation of combination inside
6314/// usize. It mutate variable in place.
6315/// It'll return None when there's no further possible
6316/// combination by given x.
6317#[allow(unused)]
6318fn gosper_combination(x : &mut u128) -> Option<()> {
6319 let u = *x & x.overflowing_neg().0; // get LSB that has 1
6320 let v = u + *x; // Add LSB to x
6321 if v == 0 {
6322 return None
6323 }
6324
6325 *x = v + (((v ^ *x) / u) >> 2);
6326 Some(())
6327}
6328
6329/// Generate binary representation of combination by
6330/// using algorithm published by Stanford university.
6331/// The different from original Gosper algorithm is
6332/// it eliminate divide operation by using built in
6333/// trailing_zeros function.
6334///
6335/// # Limitation
6336/// Gosper algorithm need to know the MSB (most significant bit).
6337/// The current largest known MSB data type is u128.
6338/// This make the implementation support up to 128 elements slice.
6339///
6340/// Reference:
6341/// - [Compute the lexicographically next bit permutation](http://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation)
6342#[inline(always)]
6343fn stanford_combination(x: &mut u128) {
6344 let t = *x | (*x - 1); // get x and set LSB set to 1
6345 // Next set to 1 the most significant bit to change,
6346 // set to 0 the least significant ones, and add the necessary 1 bits.
6347 *x = (t + 1) | (((!t & (!t).overflowing_neg().0) - 1) >> (x.trailing_zeros() + 1));
6348}
6349
6350/// Calculate factorial from given value.
6351pub fn factorial<T>(n: T) -> T where T : PrimInt + Unsigned + Product {
6352 num::range(T::one(), n + T::one()).product()
6353}
6354
6355/// Calculate factorial for two factorial division.
6356/// It'll return 1 if numerator is smaller or equals to denominator.
6357/// Otherwise, it'll short circuit the calculation by calculate only
6358/// the undivided remainder.
6359///
6360/// # Examples
6361/// ```
6362/// use permutator::divide_factorial;
6363///
6364/// // calculate 5!/3!
6365/// divide_factorial(5u8, 3u8); // return 5 * 4 = 20
6366/// // calculate 3!/5!
6367/// divide_factorial(3u32, 5u32); // return 1.
6368/// // calculate 5!/5!
6369/// divide_factorial(5u16, 5u16); // return 1.
6370/// ```
6371pub fn divide_factorial<T>(numerator: T, denominator: T) -> T where T : PrimInt + Unsigned + Product {
6372 if numerator < denominator {
6373 T::one()
6374 } else if denominator < numerator {
6375 num::range_inclusive(denominator + T::one(), numerator).product()
6376 } else {
6377 T::one()
6378 }
6379}
6380
6381/// Calculate two factorial multiply on each other.
6382/// It'll try to reduce calculation time by calculate the
6383/// common value only once.
6384///
6385/// # Examples
6386/// ```
6387/// use permutator::multiply_factorial;
6388/// // 5! * 4!
6389/// multiply_factorial(5u32, 4u32); // calculate 4! and power it by 2 then multiply by 5.
6390/// multiply_factorial(4u32, 5u32); // perform similar to above step.
6391/// multiply_factorial(5u128, 5u128); // calculate 5! and power it by 2.
6392/// ```
6393pub fn multiply_factorial<T>(fact1: T, fact2: T) -> T where T : PrimInt + Unsigned + Product {
6394 if fact1 < fact2 {
6395 let common = factorial(fact1);
6396 common.pow(2) * num::range_inclusive(fact1 + T::one(), fact2).product()
6397 } else if fact2 < fact1 {
6398 let common = factorial(fact2);
6399 common.pow(2) * num::range_inclusive(fact2 + T::one(), fact1).product()
6400 } else {
6401 return factorial(fact1).pow(2);
6402 }
6403}
6404
6405/// Initiate a first combination along with Gospel's map for further
6406/// combination calculation.
6407/// The name k_set refer to the use case of k-permutation.
6408/// It's first k combination of data `d` inside single set.
6409fn create_k_set<T>(d : &[T], width : usize) -> (Vec<&T>, u128) {
6410 let mask = (1 << width) - 1;
6411 let mut copied_mask = mask;
6412 let mut i = 0;
6413 let mut subset = Vec::new();
6414 while copied_mask > 0 {
6415 if copied_mask & 1 == 1 {
6416 subset.push(&d[i]);
6417 }
6418 i += 1;
6419 copied_mask >>= 1;
6420 }
6421 (subset, mask)
6422}
6423
6424/// Similar to create_k_set but return result through unsafe pointer
6425/// # Parameters
6426/// - `d` A raw data to get a subset `k`
6427/// - `width` A size of subset, AKA `k`
6428/// - `result` A mutable pointer that will be stored `k` subset
6429/// - `mask` A gosper bit map
6430/// # See
6431/// - [create_k_set](fn.create_k_set.html)
6432unsafe fn unsafe_create_k_set<'a, T>(d : &'a[T], width : usize, result : *mut [&'a T], mask : &mut u128) {
6433 *mask = (1 << width) - 1;
6434 let mut copied_mask = *mask;
6435 let mut i = 0;
6436 let mut j = 0;
6437
6438 while copied_mask > 0 {
6439 if copied_mask & 1 == 1 {
6440 (*result)[j] = &d[i];
6441 j += 1;
6442 }
6443 i += 1;
6444 copied_mask >>= 1;
6445 }
6446}
6447
6448/// Similar to create_k_set but return result through Rc<RefCell<&'a mut[&'a T]>>
6449/// # Parameters
6450/// - `d` A raw data to get a subset `k`
6451/// - `width` A size of subset, AKA `k`
6452/// - `result` An ref to Rc<RefCell<>> storing mutable slice that will be stored `k` subset
6453/// - `mask` A gosper bit map
6454/// # See
6455/// - [create_k_set](fn.create_k_set.html)
6456fn create_k_set_in_cell<'a, T>(d : &'a[T], width : usize, result : &Rc<RefCell<&'a mut[&'a T]>>, mask : &mut u128) {
6457 *mask = (1 << width) - 1;
6458 let mut copied_mask = *mask;
6459 let mut i = 0;
6460 let mut j = 0;
6461
6462 while copied_mask > 0 {
6463 if copied_mask & 1 == 1 {
6464 result.borrow_mut()[j] = &d[i];
6465 j += 1;
6466 }
6467 i += 1;
6468 copied_mask >>= 1;
6469 }
6470}
6471
6472/// Similar to create_k_set but return result through Rc<RefCell<&'a mut[&'a T]>>
6473/// # Parameters
6474/// - `d` A raw data to get a subset `k`
6475/// - `width` A size of subset, AKA `k`
6476/// - `result` An ref to Rc<RefCell<>> storing mutable slice that will be stored `k` subset
6477/// - `mask` A gosper bit map
6478/// # See
6479/// - [create_k_set](fn.create_k_set.html)
6480fn create_k_set_sync<'a, T>(d : &'a[T], width : usize, result : &Arc<RwLock<Vec<&'a T>>>, mask : &mut u128) {
6481 *mask = (1 << width) - 1;
6482 let mut copied_mask = *mask;
6483 let mut i = 0;
6484 let mut j = 0;
6485
6486 while copied_mask > 0 {
6487 if copied_mask & 1 == 1 {
6488 result.write().unwrap()[j] = &d[i];
6489 j += 1;
6490 }
6491 i += 1;
6492 copied_mask >>= 1;
6493 }
6494}
6495
6496/// Swap variable into data k sized data set. It take a pair of k size data set with
6497/// associated Gospel's map. It'll then replace all data in set with new combination
6498/// map generated by Gospel's algorithm. The replacement is done in place.
6499/// The function return `Some(())` to indicate that new combination replacement is done.
6500/// If there's no further combination, it'll return `None`.
6501#[inline(always)]
6502fn swap_k<'a, 'b : 'a, 'c : 'b, T : 'c>(subset_map : (&'a mut [&'b T], &mut u128), d : &'c[T]) -> Option<()> {
6503 // Replace original Gosper's algorithm by using enhanced version from Stanford University instead
6504 // if let Some(_) = gosper_combination(subset_map.1) {
6505 // let mut copied_mask = *subset_map.1;
6506 // let n = d.len();
6507 // let mut i = 0;
6508 // let mut j = 0;
6509 // while copied_mask > 0 && i < n {
6510 // if copied_mask & 1 == 1 {
6511 // subset_map.0[j] = &d[i];
6512 // j += 1;
6513 // }
6514 // i += 1;
6515 // copied_mask >>= 1;
6516 // }
6517
6518 // if copied_mask > 0 { // mask goes over the length of `d` now.
6519 // None
6520 // } else {
6521 // Some(())
6522 // }
6523 // } else {
6524 // None
6525 // }
6526
6527 stanford_combination(subset_map.1);
6528 let mut copied_mask = *subset_map.1;
6529 let n = d.len();
6530 let mut i = 0;
6531 let mut j = 0;
6532 while copied_mask > 0 && i < n {
6533 if copied_mask & 1 == 1 {
6534 subset_map.0[j] = &d[i];
6535 j += 1;
6536 }
6537 i += 1;
6538 copied_mask >>= 1;
6539 }
6540
6541 if copied_mask > 0 { // mask goes over the length of `d` now.
6542 None
6543 } else {
6544 Some(())
6545 }
6546}
6547/// Swap variable into data k sized data set. It take a pair of k size data set with
6548/// associated Gospel's map. It'll then replace all data in set with new combination
6549/// map generated by Gospel's algorithm. The replacement is done in place.
6550/// The function return `Some(())` to indicate that new combination replacement is done.
6551/// If there's no further combination, it'll return `None`.
6552fn swap_k_in_cell<'a, 'b : 'a, T>(subset_map : (&Rc<RefCell<&'a mut [&'b T]>>, &mut u128), d : &'b[T]) -> Option<()> {
6553 // Replace original Gosper's algorithm by using enhanced version from Stanford University instead
6554 // if let Some(_) = gosper_combination(subset_map.1) {
6555 // let mut copied_mask = *subset_map.1;
6556 // let n = d.len();
6557 // let mut i = 0;
6558 // let mut j = 0;
6559 // while copied_mask > 0 && i < n {
6560 // if copied_mask & 1 == 1 {
6561 // subset_map.0[j] = &d[i];
6562 // j += 1;
6563 // }
6564 // i += 1;
6565 // copied_mask >>= 1;
6566 // }
6567
6568 // if copied_mask > 0 { // mask goes over the length of `d` now.
6569 // None
6570 // } else {
6571 // Some(())
6572 // }
6573 // } else {
6574 // None
6575 // }
6576
6577 stanford_combination(subset_map.1);
6578 let mut copied_mask = *subset_map.1;
6579 let n = d.len();
6580 let mut i = 0;
6581 let mut j = 0;
6582 while copied_mask > 0 && i < n {
6583 if copied_mask & 1 == 1 {
6584 subset_map.0.borrow_mut()[j] = &d[i];
6585 j += 1;
6586 }
6587 i += 1;
6588 copied_mask >>= 1;
6589 }
6590
6591 if copied_mask > 0 { // mask goes over the length of `d` now.
6592 None
6593 } else {
6594 Some(())
6595 }
6596}
6597
6598/// Swap variable into data k sized data set. It take a pair of k size data set with
6599/// associated Gospel's map. It'll then replace all data in set with new combination
6600/// map generated by Gospel's algorithm. The replacement is done in place.
6601/// The function return `Some(())` to indicate that new combination replacement is done.
6602/// If there's no further combination, it'll return `None`.
6603fn swap_k_sync<'a, 'b : 'a, T>(subset_map : (&Arc<RwLock<Vec<&'b T>>>, &mut u128), d : &'b[T]) -> Option<()> {
6604 // Replace original Gosper's algorithm by using enhanced version from Stanford University instead
6605 // if let Some(_) = gosper_combination(subset_map.1) {
6606 // let mut copied_mask = *subset_map.1;
6607 // let n = d.len();
6608 // let mut i = 0;
6609 // let mut j = 0;
6610 // while copied_mask > 0 && i < n {
6611 // if copied_mask & 1 == 1 {
6612 // subset_map.0[j] = &d[i];
6613 // j += 1;
6614 // }
6615 // i += 1;
6616 // copied_mask >>= 1;
6617 // }
6618
6619 // if copied_mask > 0 { // mask goes over the length of `d` now.
6620 // None
6621 // } else {
6622 // Some(())
6623 // }
6624 // } else {
6625 // None
6626 // }
6627
6628 stanford_combination(subset_map.1);
6629 let mut copied_mask = *subset_map.1;
6630 let n = d.len();
6631 let mut i = 0;
6632 let mut j = 0;
6633 while copied_mask > 0 && i < n {
6634 if copied_mask & 1 == 1 {
6635 subset_map.0.write().unwrap()[j] = &d[i];
6636 j += 1;
6637 }
6638 i += 1;
6639 copied_mask >>= 1;
6640 }
6641
6642 if copied_mask > 0 { // mask goes over the length of `d` now.
6643 None
6644 } else {
6645 Some(())
6646 }
6647}
6648
6649#[cfg(test)]
6650pub mod test {
6651 use super::*;
6652 use std::thread;
6653 use std::sync::mpsc;
6654 use std::sync::mpsc::{SyncSender, Receiver};
6655
6656 #[test]
6657 fn test_get_cartesian_for() {
6658 let words = ["word1", "word2", "word3"];
6659 let result = [[&words[0], &words[0]], [&words[0], &words[1]],
6660 [&words[0], &words[2]], [&words[1], &words[0]],
6661 [&words[1], &words[1]], [&words[1], &words[2]],
6662 [&words[2], &words[0]], [&words[2], &words[1]],
6663 [&words[2], &words[2]]];
6664 for (i, r) in result.iter().enumerate() {
6665 assert_eq!(get_cartesian_for(&words, 2, i).unwrap(), r, "Fail to get cartesian product degree 2@i={}", i);
6666 }
6667
6668 assert_eq!(get_cartesian_for(&words, 4, 0).is_err(), true, "Unexpected no error when degree is larger than size of objects");
6669
6670 for (i, w) in words.iter().enumerate() {
6671 assert_eq!(get_cartesian_for(&words, 1, i).unwrap()[0], w, "Fail to get cartesian product degree 1@i={}", i);
6672 }
6673
6674 assert_eq!(get_cartesian_for(&words, 0, 0).unwrap().len(), 0, "Fail to get cartesian product degree 0");
6675 }
6676
6677 #[test]
6678 fn test_get_permutation_for() {
6679 let words = ["word1", "word2", "word3"];
6680 let result = [[&words[0], &words[1]], [&words[0], &words[2]],
6681 [&words[1], &words[0]], [&words[1], &words[2]],
6682 [&words[2], &words[0]], [&words[2], &words[1]]];
6683 for (i, r) in result.iter().enumerate() {
6684 assert_eq!(get_permutation_for(&words, 2, i).unwrap(), r, "Fail to get permutation degree 2@i={}", i);
6685 }
6686
6687 assert_eq!(get_permutation_for(&words, 4, 0).is_err(), true, "Unexpected no error when degree is larger than size of objects");
6688
6689 for (i, w) in words.iter().enumerate() {
6690 assert_eq!(get_permutation_for(&words, 1, i).unwrap()[0], w, "Fail to get permutation degree 1@i={}", i);
6691 }
6692
6693 assert_eq!(get_permutation_for(&words, 0, 0).unwrap().len(), 0, "Fail to get permutation degree 0");
6694 }
6695
6696 #[test]
6697 fn test_heap_permutation_6() {
6698 let mut data = [1, 2, 3, 4, 5, 6];
6699 let mut counter = 0;
6700 heap_permutation(&mut data, |_| {
6701 counter +=1;
6702 });
6703
6704 assert_eq!(720, counter);
6705 }
6706
6707 #[test]
6708 fn test_heap_permutation_10() {
6709 use std::time::{Instant};
6710 let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
6711 let mut counter = 0;
6712 let timer = Instant::now();
6713 // println!("{:?}", data);
6714 heap_permutation(&mut data, |_| {
6715 // println!("{:?}", perm);
6716 counter += 1;
6717 });
6718
6719 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
6720 assert_eq!(3628800, counter);
6721 }
6722
6723 #[allow(non_snake_case, unused)]
6724 #[test]
6725 fn test_CartesianProduct() {
6726 use std::time::Instant;
6727 let data : &[&[usize]] = &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
6728 let cart = CartesianProductIterator::new(&data);
6729 let mut counter = 0;
6730 let timer = Instant::now();
6731
6732 for p in cart {
6733 // println!("{:?}", p);
6734 counter += 1;
6735 }
6736
6737 assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
6738 println!("Total {} products done in {:?}", counter, timer.elapsed());
6739 }
6740
6741 #[allow(non_snake_case, unused)]
6742 #[test]
6743 fn test_SelfCartesianProduct() {
6744 use std::time::Instant;
6745 let data : &[usize] = &[1, 2, 3];
6746 let n = 3;
6747 let cart = SelfCartesianProductIterator::new(&data, n);
6748 let mut counter = 0;
6749 let timer = Instant::now();
6750
6751 for p in cart {
6752 println!("{:?}", p);
6753 counter += 1;
6754 }
6755
6756 assert_eq!(data.len().pow(n as u32), counter);
6757 println!("Total {} products done in {:?}", counter, timer.elapsed());
6758 }
6759
6760 #[allow(non_snake_case, unused)]
6761 #[test]
6762 fn test_CartesianProduct_reset() {
6763 use std::time::Instant;
6764 let data : &[&[usize]] = &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
6765 let mut counter = 0;
6766 let mut result : Vec<&usize> = vec![&data[0][0]; data.len()];
6767 unsafe {
6768 let mut cart = CartesianProductRefIter::new(&data, result.as_mut_slice());
6769 let timer = Instant::now();
6770
6771 while let Some(_) = cart.next() {
6772 counter += 1;
6773 }
6774
6775 let all_possible = data.iter().fold(1, |cum, domain| {cum * domain.len()});
6776 assert_eq!(all_possible, counter);
6777
6778 counter = 0;
6779 // it shall end immediately because it's already exhausted
6780 while let Some(_) = cart.next() {
6781 counter += 1;
6782 }
6783
6784 assert_eq!(0, counter);
6785
6786 cart.reset();
6787 counter = 0;
6788
6789 // now it shall start iterating again.
6790 for _ in cart {
6791 counter += 1;
6792 }
6793
6794 assert_eq!(all_possible, counter);
6795
6796 println!("Total {} products done in {:?}", counter, timer.elapsed());
6797 }
6798 }
6799
6800 #[allow(non_snake_case, unused)]
6801 #[test]
6802 fn test_CartesianProduct_mimic_iterator() {
6803 use std::time::Instant;
6804 let data : &[&[usize]] = &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9], &[10, 11, 12,]];
6805 let mut result : Vec<&usize> = vec![&data[0][0]; data.len()];
6806 unsafe {
6807 let mut cart = CartesianProductRefIter::new(&data, result.as_mut_slice());
6808 let mut counter = 0;
6809 let timer = Instant::now();
6810
6811 for _ in cart {
6812 // println!("{:?}", p);
6813 counter += 1;
6814 }
6815
6816 assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
6817 println!("Total {} products done in {:?}", counter, timer.elapsed());
6818 }
6819 }
6820
6821 #[allow(non_snake_case, unused)]
6822 #[test]
6823 fn test_SelfCartesianProduct_cell() {
6824 use std::time::Instant;
6825 let data : &[usize] = &[1, 2, 3];
6826 let n = 3;
6827 let mut result = vec![&data[0]; n];
6828 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
6829 let cart = SelfCartesianProductCellIter::new(&data, n, Rc::clone(&shared));
6830 let mut counter = 0;
6831 let timer = Instant::now();
6832
6833 for _ in cart {
6834 println!("{:?}", &*shared.borrow());
6835 counter += 1;
6836 }
6837
6838 assert_eq!(data.len().pow(n as u32), counter);
6839 println!("Total {} products done in {:?}", counter, timer.elapsed());
6840 }
6841
6842 #[allow(non_snake_case, unused)]
6843 #[test]
6844 fn test_SelfCartesianProduct_ref() {
6845 use std::time::Instant;
6846 let data : &[usize] = &[1, 2, 3];
6847 let n = 3;
6848 let result : &mut[&usize] = &mut vec![&data[0]; n];
6849 let shared = result as *mut[&usize];
6850 unsafe {
6851 let cart = SelfCartesianProductRefIter::new(&data, n, result);
6852 let mut counter = 0;
6853 let timer = Instant::now();
6854
6855 for _ in cart {
6856 println!("{:?}", &*shared);
6857 counter += 1;
6858 }
6859
6860 assert_eq!(data.len().pow(n as u32), counter);
6861 println!("Total {} products done in {:?}", counter, timer.elapsed());
6862 }
6863 }
6864
6865 #[allow(non_snake_case, unused)]
6866 #[test]
6867 fn test_CartesianProduct_mimic_iterator_2() {
6868 use std::time::Instant;
6869 let data : &[&[usize]] = &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9], &[10, 11, 12,]];
6870 let mut result : Vec<&usize> = vec![&data[0][0]; data.len()];
6871 unsafe {
6872 let mut cart = CartesianProductRefIter::new(&data, result.as_mut_slice() as *mut [&usize]);
6873 let mut counter = 0;
6874 let timer = Instant::now();
6875
6876 for _ in cart {
6877 // println!("{:?}", p);
6878 counter += 1;
6879 }
6880
6881 assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
6882 println!("Total {} products done in {:?}", counter, timer.elapsed());
6883 }
6884 }
6885
6886 #[allow(non_snake_case, unused)]
6887 #[test]
6888 fn test_CartesianProduct_trait() {
6889 use std::time::Instant;
6890
6891 let mut counter = 0;
6892 let timer = Instant::now();
6893 let data : &[&[u8]]= &[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]];
6894
6895 data.cart_prod().for_each(|p| {
6896 counter += 1;
6897 });
6898
6899 assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
6900 println!("Total {} products done in {:?}", counter, timer.elapsed());
6901 }
6902
6903 #[allow(non_snake_case, unused)]
6904 #[test]
6905 fn test_CartesianProduct_shared_trait() {
6906 use std::time::Instant;
6907
6908 let mut counter = 0;
6909 let timer = Instant::now();
6910 let data : &[&[u8]]= &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9], &[10, 11, 12,]];
6911 let mut result = vec![&data[0][0]; data.len()];
6912 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
6913
6914 (data, Rc::clone(&shared)).cart_prod().for_each(|_| {
6915 counter += 1;
6916 });
6917
6918 assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
6919 println!("Total {} products done in {:?}", counter, timer.elapsed());
6920 }
6921
6922 #[allow(non_snake_case, unused)]
6923 #[test]
6924 fn test_CartesianProduct_ptr_trait() {
6925 use std::time::Instant;
6926
6927 let mut counter = 0;
6928 let timer = Instant::now();
6929 let data : &[&[u8]]= &[&[1, 2], &[3, 4, 5, 6], &[7, 8, 9], &[10, 11, 12,]];
6930 let mut result = vec![&data[0][0]; data.len()];
6931 let shared = result.as_mut_slice() as *mut [&u8];
6932
6933 (data, shared).cart_prod().for_each(|_| {
6934 counter += 1;
6935 });
6936
6937 assert_eq!(data.iter().fold(1, |cum, domain| {cum * domain.len()}), counter);
6938 println!("Total {} products done in {:?}", counter, timer.elapsed());
6939 }
6940
6941 #[allow(unused)]
6942 #[test]
6943 fn test_k_permutation_fn() {
6944 use std::time::{Instant};
6945 let data = [1, 2, 3, 4, 5];
6946 let k = 3;
6947 let mut counter = 0;
6948 let timer = Instant::now();
6949 k_permutation(&data, k, |permuted| {
6950 // uncomment line below to print all k-permutation
6951 println!("{}:{:?}", counter, permuted);
6952 counter += 1;
6953 });
6954
6955 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
6956 assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
6957 }
6958
6959 #[allow(unused)]
6960 #[should_panic]
6961 #[test]
6962 fn test_k_permutation_empty_dom() {
6963 use std::time::{Instant};
6964 let data : &[i32] = &[];
6965 let k = 1;
6966 let mut counter = 0;
6967 let timer = Instant::now();
6968 k_permutation(&data, k, |permuted| {
6969 // uncomment line below to print all k-permutation
6970 println!("{}:{:?}", counter, permuted);
6971 counter += 1;
6972 });
6973
6974 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
6975 assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
6976 }
6977
6978 #[allow(unused)]
6979 #[test]
6980 fn test_k_permutation_k_1() {
6981 use std::time::{Instant};
6982 let data : &[i32] = &[1, 2];
6983 let k = 1;
6984 let mut counter = 0;
6985 let timer = Instant::now();
6986 k_permutation(&data, k, |permuted| {
6987 // uncomment line below to print all k-permutation
6988 println!("{}:{:?}", counter, permuted);
6989 counter += 1;
6990 });
6991
6992 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
6993 assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
6994 }
6995
6996 #[allow(unused)]
6997 #[test]
6998 #[ignore]
6999 fn test_large_k_permutation() {
7000 use std::time::{Instant};
7001 let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
7002 let k = 11;
7003 let mut counter = 0;
7004 let timer = Instant::now();
7005 k_permutation(&data, k, |permuted| {
7006 // uncomment line below to print all k-permutation
7007 // println!("{}:{:?}", counter, permuted);
7008 counter += 1;
7009 });
7010
7011 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
7012 assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
7013 }
7014
7015
7016 // #[test]
7017 // fn test_gosper_combination() {
7018 // let mut comb = 7;
7019
7020 // for _ in 0..40 {
7021 // gosper_combination(&mut comb);
7022 // println!("next_combination is {:b}", comb);
7023 // }
7024
7025 // }
7026
7027 #[allow(non_snake_case, unused)]
7028 #[test]
7029 fn test_HeapPermutation() {
7030 use std::time::{Instant};
7031 let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
7032 // let data = &mut [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
7033 // println!("0:{:?}", data);
7034 let mut permutator = HeapPermutationIterator::new(&mut data);
7035 let timer = Instant::now();
7036 let mut counter = 1;
7037
7038 while let Some(permutated) = permutator.next() {
7039 // println!("{}:{:?}", counter, permutated);
7040 counter += 1;
7041 }
7042
7043 assert_eq!(6, counter);
7044 println!("Done {} permutations in {:?}", counter, timer.elapsed());
7045 }
7046
7047 #[allow(non_snake_case, unused)]
7048 #[test]
7049 fn test_XPermutationIterator() {
7050 use std::time::{Instant};
7051 let mut data : Vec<u32> = (0..3).map(|num| num).collect();
7052 let mut permutator = XPermutationIterator::new(&data, |_| true);
7053 let timer = Instant::now();
7054 let mut counter = 0;
7055
7056 while let Some(permutated) = permutator.next() {
7057 // println!("{}:{:?}", counter, permutated);
7058 counter += 1;
7059 }
7060
7061 assert_eq!(factorial(data.len()), counter);
7062 println!("Done {} permutations in {:?}", counter, timer.elapsed());
7063 }
7064
7065 #[allow(non_snake_case, unused)]
7066 #[test]
7067 fn test_XPermutationCellIter() {
7068 use std::time::{Instant};
7069 let mut data : Vec<u32> = (0..3).map(|num| num).collect();
7070 let mut result = vec![&data[0]; data.len()];
7071 let share = Rc::new(RefCell::new(result.as_mut_slice()));
7072 let mut permutator = XPermutationCellIter::new(&data, Rc::clone(&share), |_| true);
7073 let timer = Instant::now();
7074 let mut counter = 0;
7075
7076 while let Some(_) = permutator.next() {
7077 println!("{}:{:?}", counter, &*share.borrow());
7078 counter += 1;
7079 }
7080
7081 assert_eq!(factorial(data.len()), counter);
7082 println!("Done {} permutations in {:?}", counter, timer.elapsed());
7083 }
7084
7085 #[allow(non_snake_case, unused)]
7086 #[test]
7087 fn test_XPermutationRefIter() {
7088 use std::time::{Instant};
7089 let mut data : Vec<u32> = (0..3).map(|num| num).collect();
7090 let mut result = vec![&data[0]; data.len()];
7091 let share = result.as_mut_slice() as *mut [&u32];
7092 unsafe {
7093 let mut permutator = XPermutationRefIter::new(&data, share, |_| true);
7094 let timer = Instant::now();
7095 let mut counter = 0;
7096
7097 while let Some(_) = permutator.next() {
7098 println!("{}:{:?}", counter, result);
7099 counter += 1;
7100 }
7101
7102 assert_eq!(factorial(data.len()), counter);
7103 println!("Done {} permutations in {:?}", counter, timer.elapsed());
7104 }
7105 }
7106
7107 #[allow(non_snake_case, unused)]
7108 #[ignore]
7109 #[test]
7110 fn test_XPermutationIterator_mt() {
7111 use std::time::{Instant};
7112 let data : Vec<usize> = (0..3).map(|num| num).collect();
7113 let threads = 3;
7114 let chunk = data.len() / threads;
7115 let (tx, rx) = mpsc::channel();
7116
7117 for i in 0..threads {
7118 let start = chunk * i;
7119 let end = match i {
7120 j if j == threads - 1 => data.len(), // last thread handle remaining work
7121 _ => chunk * (i + 1)
7122 };
7123
7124
7125 let l_dat = data.to_owned(); // copy data for each thread
7126 let end_sig = tx.clone();
7127
7128 thread::spawn(move || {
7129 let timer = Instant::now();
7130
7131 let perm = XPermutationIterator::new(
7132 &l_dat,
7133 |v| *v[0] >= start && *v[0] < end // skip branch that is outside the start/end
7134 );
7135
7136 let mut counter = 0u64;
7137
7138 for p in perm {
7139 // each permutation is stored in p
7140 counter += 1;
7141 }
7142
7143 end_sig.send(i).unwrap();
7144 });
7145 }
7146
7147 let main = thread::spawn(move || { // main thread
7148 let mut counter = 0;
7149
7150 while counter < threads {
7151 let i = rx.recv().unwrap();
7152 // do something
7153 counter += 1;
7154 }
7155 });
7156
7157 main.join().unwrap();
7158 }
7159
7160 #[allow(non_snake_case, unused)]
7161 #[test]
7162 fn test_HeapPermutation_reset() {
7163 use std::time::{Instant};
7164 let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
7165 // let data = &mut [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
7166 println!("0:{:?}", data);
7167 let mut permutator = HeapPermutationIterator::new(&mut data);
7168 let timer = Instant::now();
7169 let mut counter = 1;
7170
7171 while let Some(permutated) = permutator.next() {
7172 // println!("{}:{:?}", counter, permutated);
7173 counter += 1;
7174 }
7175
7176 assert_eq!(6, counter);
7177
7178 let mut counter = 1;
7179
7180 while let Some(permutated) = permutator.next() {
7181 // println!("{}:{:?}", counter, permutated);
7182 counter += 1;
7183 }
7184
7185 assert_eq!(1, counter);
7186
7187 permutator.reset();
7188 let mut counter = 1;
7189
7190 while let Some(permutated) = permutator.next() {
7191 // println!("{}:{:?}", counter, permutated);
7192 counter += 1;
7193 }
7194
7195 assert_eq!(6, counter);
7196 }
7197
7198 #[allow(non_snake_case, unused)]
7199 #[test]
7200 fn test_HeapPermutationIntoIterator() {
7201 use std::time::{Instant};
7202 let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
7203 // let data = &mut [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
7204 println!("0:{:?}", data);
7205 let permutator = HeapPermutationIterator::new(&mut data);
7206 let timer = Instant::now();
7207 let mut counter = 1;
7208
7209 permutator.into_iter().for_each(|permutated| {counter += 1;});
7210
7211 println!("Done {} permutations in {:?}", counter, timer.elapsed());
7212 assert_eq!(6, counter);
7213 }
7214
7215 #[allow(non_snake_case, unused)]
7216 #[test]
7217 fn test_HeapPermutationRefIterator() {
7218 use std::time::{Instant};
7219 let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
7220 // let data = &mut [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
7221 // println!("0:{:?}", data);
7222 unsafe {
7223 let mut permutator = HeapPermutationRefIter::new(data.as_mut_slice());
7224 let timer = Instant::now();
7225 let mut counter = 1;
7226
7227 while let Some(permutated) = permutator.next() {
7228 // println!("{}:{:?}", counter, permutated);
7229 counter += 1;
7230 }
7231
7232 assert_eq!(6, counter);
7233 println!("Done perm_ref {} permutations in {:?}", counter, timer.elapsed());
7234 }
7235 }
7236
7237 #[allow(non_snake_case, unused)]
7238 #[test]
7239 fn test_HeapPermutationCellIterIterator() {
7240 use std::time::{Instant};
7241 let mut data : Vec<String> = (1..=3).map(|num| {format!("some ridiculously long word prefix without any point{}", num)}).collect();
7242 let shared = Rc::new(RefCell::new(data.as_mut_slice()));
7243 // let data = &mut [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
7244 let permutator = HeapPermutationCellIter::new(Rc::clone(&shared));
7245 println!("{}:{:?}", 0, &*shared.borrow());
7246 let timer = Instant::now();
7247 let mut counter = 1;
7248
7249 for _ in permutator {
7250 println!("{}:{:?}", counter, &*shared.borrow());
7251 counter += 1;
7252 }
7253
7254 println!("Done {} permutations in {:?}", counter, timer.elapsed());
7255 assert_eq!(6, counter);
7256 }
7257
7258 #[allow(non_snake_case, unused)]
7259 #[test]
7260 fn test_GosperCombinationIterator() {
7261 use std::time::{Instant};
7262 let gosper = GosperCombinationIterator::new(&[1, 2, 3, 4, 5], 3);
7263 let mut counter = 0;
7264 let timer = Instant::now();
7265
7266 for combination in gosper {
7267 // println!("{}:{:?}", counter, combination);
7268 counter += 1;
7269 }
7270
7271 println!("Total {} combinations in {:?}", counter, timer.elapsed());
7272 assert_eq!(10, counter);
7273 }
7274
7275 #[allow(non_snake_case, unused)]
7276 #[test]
7277 fn test_LargeCombinationIterator() {
7278 use std::time::{Instant};
7279 let data : &[i32] = &[1, 2, 3, 4, 5];
7280 let k = 3;
7281 let mut combs = LargeCombinationIterator::new(data, k);
7282 let mut counter = 0;
7283 let timer = Instant::now();
7284
7285 for combination in combs.iter() {
7286 println!("{}:{:?}", counter, combination);
7287 counter += 1;
7288 }
7289
7290 println!("Total {} combinations in {:?}", counter, timer.elapsed());
7291 assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
7292
7293 // test continue on exhausted iterator
7294 for combination in combs.iter() {
7295 println!("{}:{:?}", counter, combination);
7296 counter += 1;
7297 }
7298 assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
7299
7300 // test reset the iterator
7301 combs.reset();
7302 let mut counter = 0;
7303 let timer = Instant::now();
7304
7305 for combination in combs.iter() {
7306 println!("{}:{:?}", counter, combination);
7307 counter += 1;
7308 }
7309
7310 println!("Total {} combinations in {:?}", counter, timer.elapsed());
7311 assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
7312 }
7313
7314 #[allow(non_snake_case, unused)]
7315 #[test]
7316 fn test_LargeCombinationIterator_single() {
7317 use std::time::{Instant};
7318 let data : &[i32] = &[1, 2, 3, 4, 5];
7319 let k = 1;
7320 let mut combs = LargeCombinationIterator::new(data, k);
7321 let mut counter = 0;
7322 let timer = Instant::now();
7323
7324 for combination in combs.iter() {
7325 println!("{}:{:?}", counter, combination);
7326 counter += 1;
7327 }
7328
7329 println!("Total {} combinations in {:?}", counter, timer.elapsed());
7330 assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
7331
7332 // test continue on exhausted iterator
7333 for combination in combs.iter() {
7334 println!("{}:{:?}", counter, combination);
7335 counter += 1;
7336 }
7337 assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
7338
7339 // test reset the iterator
7340 combs.reset();
7341 let mut counter = 0;
7342 let timer = Instant::now();
7343
7344 for combination in combs.iter() {
7345 println!("{}:{:?}", counter, combination);
7346 counter += 1;
7347 }
7348
7349 println!("Total {} combinations in {:?}", counter, timer.elapsed());
7350 assert_eq!(divide_factorial(data.len(), data.len() - k) / factorial(k), counter);
7351 }
7352
7353 #[allow(non_snake_case, unused)]
7354 #[test]
7355 fn test_GosperCombinationIteratorUnsafe() {
7356 use std::time::{Instant};
7357 let data = &[1, 2, 3, 4, 5, 6];
7358 let r = 4;
7359 let mut counter = 0;
7360 let timer = Instant::now();
7361 let mut result = vec![&data[0]; r];
7362 unsafe {
7363 let mut gosper = GosperCombinationRefIter::new(data, r, result.as_mut_slice() as *mut [&i32]);
7364
7365 for _ in gosper {
7366 // println!("{}:{:?}", counter, combination);
7367 counter += 1;
7368 }
7369
7370 println!("Total {} combinations in {:?}", counter, timer.elapsed());
7371 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7372 }
7373 }
7374
7375 #[allow(non_snake_case, unused)]
7376 #[test]
7377 fn test_GosperCombinationCellIter() {
7378 use std::time::{Instant};
7379 let data = &[1, 2, 3, 4, 5, 6];
7380 let r = 3;
7381 let mut counter = 0;
7382 let timer = Instant::now();
7383 let mut result = vec![&data[0]; r];
7384 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
7385
7386 let mut gosper = GosperCombinationCellIter::new(data, r, Rc::clone(&shared));
7387
7388 for _ in gosper {
7389 // println!("{}:{:?}", counter, &*shared.borrow());
7390 counter += 1;
7391 }
7392
7393 println!("Total {} combinations in {:?}", counter, timer.elapsed());
7394 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7395 }
7396
7397 #[allow(non_snake_case, unused)]
7398 #[test]
7399 fn test_GosperCombinationIteratorAlike_reset() {
7400 use std::time::{Instant};
7401 let data = &[1, 2, 3, 4, 5];
7402 let r = 3;
7403 let mut counter = 0;
7404 let timer = Instant::now();
7405 let mut result = vec![&data[0]; r];
7406 unsafe {
7407 let mut gosper = GosperCombinationRefIter::new(data, r, result.as_mut_slice() as *mut [&i32]);
7408 let mut iter = gosper.into_iter();
7409
7410 while let Some(_) = iter.next() {
7411 println!("{}:{:?}", counter, result);
7412 counter += 1;
7413 }
7414
7415 println!("Total {} combinations in {:?}", counter, timer.elapsed());
7416 let all_possible = divide_factorial(data.len(), r) / factorial(data.len() - r);
7417 assert_eq!(all_possible, counter);
7418 counter = 0;
7419
7420 while let Some(_) = iter.next() {
7421 // println!("{}:{:?}", counter, combination);
7422 counter += 1;
7423 }
7424 assert_eq!(0, counter);
7425 iter.reset();
7426 counter = 0;
7427
7428 while let Some(_) = iter.next() {
7429 // println!("{}:{:?}", counter, combination);
7430 counter += 1;
7431 }
7432 assert_eq!(all_possible, counter);
7433 }
7434 }
7435
7436 #[allow(non_snake_case, unused)]
7437 #[test]
7438 fn test_KPermutationIterator() {
7439 use std::time::Instant;
7440 let data = [1, 2, 3, 4, 5];
7441 let k = 3;
7442 let permutator = KPermutationIterator::new(&data, k);
7443 let mut counter = 0;
7444 // println!("Begin testing KPermutation");
7445 let timer = Instant::now();
7446
7447 for permuted in permutator {
7448 println!("{}:{:?}", counter, permuted);
7449 counter += 1;
7450 }
7451
7452 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
7453 assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
7454 }
7455
7456 #[allow(non_snake_case, unused)]
7457 #[test]
7458 fn test_KPermutationIteratorBound() {
7459 use std::time::Instant;
7460 let data = [1, 2, 3, 4];
7461 let k = 4;
7462 let permutator = KPermutationIterator::new(&data, k);
7463 let mut counter = 0;
7464 // println!("Begin testing KPermutation");
7465 let timer = Instant::now();
7466
7467 for permuted in permutator {
7468 println!("{}:{:?}", counter, permuted);
7469 counter += 1;
7470 }
7471
7472 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
7473 assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
7474 }
7475
7476 #[allow(non_snake_case)]
7477 #[test]
7478 fn test_KPermutation_into_Cell() {
7479 use std::time::Instant;
7480
7481 let data : &[i32] = &[1, 2, 3, 4, 5];
7482 let mut counter = 0;
7483 let k = 3;
7484 let mut result : Vec<&i32> = vec![&data[0]; k];
7485 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
7486 let timer = Instant::now();
7487 KPermutationCellIter::new(data, k, Rc::clone(&shared)).into_iter().for_each(|_| {
7488 // println!("{:?}", &*shared);
7489 counter += 1;
7490 });
7491
7492 println!("Total {} combination done in {:?}", counter, timer.elapsed());
7493 assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
7494 }
7495
7496 #[allow(non_snake_case)]
7497 #[test]
7498 fn test_KPermutation_into_Ref() {
7499 use std::time::Instant;
7500
7501 let data : &[i32] = &[1, 2, 3, 4, 5];
7502 let mut counter = 0;
7503 let k = 3;
7504 let mut result : Vec<&i32> = vec![&data[0]; k];
7505 let shared = result.as_mut_slice() as *mut [&i32];
7506 let timer = Instant::now();
7507 unsafe {
7508 KPermutationRefIter::new(data, k, shared).into_iter().for_each(|_| {
7509 // println!("{:?}", &*shared);
7510 counter += 1;
7511 });
7512
7513 println!("Total {} combination done in {:?}", counter, timer.elapsed());
7514 assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
7515 }
7516 }
7517
7518 #[allow(unused)]
7519 #[test]
7520 fn test_cartesian_product() {
7521 use std::time::Instant;
7522 let set = (1..4).map(|item| item).collect::<Vec<u64>>();
7523 let mut data = Vec::<&[u64]>::new();
7524 for _ in 0..4 {
7525 data.push(&set);
7526 }
7527
7528 let mut counter = 0;
7529 let timer = Instant::now();
7530
7531 cartesian_product(&data, |product| {
7532 // println!("{:?}", product);
7533 counter += 1;
7534 });
7535
7536 println!("Total {} product done in {:?}", counter, timer.elapsed());
7537 }
7538
7539 #[allow(unused)]
7540 #[test]
7541 fn test_self_cartesian_product() {
7542 use std::time::Instant;
7543 let data : &[i32] = &[1, 2, 3];
7544 let n = 3;
7545
7546 let mut counter = 0;
7547 let timer = Instant::now();
7548
7549 self_cartesian_product(&data, 3, |product| {
7550 println!("{:?}", product);
7551 counter += 1;
7552 });
7553
7554 println!("Total {} product done in {:?}", counter, timer.elapsed());
7555 }
7556
7557 #[allow(unused)]
7558 #[should_panic]
7559 #[test]
7560 fn test_self_cartesian_product_zero() {
7561 use std::time::Instant;
7562 let data : &[i32] = &[1, 2, 3];
7563 let n = 0;
7564
7565 let mut counter = 0;
7566 let timer = Instant::now();
7567
7568 self_cartesian_product(&data, n, |product| {
7569 println!("{:?}", product);
7570 counter += 1;
7571 });
7572
7573 println!("Total {} product done in {:?}", counter, timer.elapsed());
7574 }
7575
7576 #[test]
7577 fn test_combination_trait() {
7578 let data = [1, 2, 3, 4, 5, 6, 7, 8];
7579 let k = 4;
7580 let mut counter = 0;
7581 for combination in data.combination(k) {
7582 println!("{:?}", combination);
7583 counter += 1;
7584 }
7585
7586 assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); // n!/(k!(n-k!))
7587 }
7588
7589 #[test]
7590 fn test_combination_trait_share() {
7591 let data : &[i32] = &[1, 2, 3, 4, 5, 6, 7, 8];
7592 let k = 3;
7593 let mut result = vec![&data[0]; k];
7594 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
7595 let combination_op = (data, shared);
7596 let mut counter = 0;
7597 for combination in combination_op.combination(k) {
7598 println!("{:?}", combination);
7599 counter += 1;
7600 }
7601
7602 assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); // n!/(k!(n-k!))
7603 }
7604
7605 #[test]
7606 fn test_combination_trait_ptr() {
7607 let data : &[i32] = &[1, 2, 3, 4, 5, 6];
7608 let k = 4;
7609 let mut result = vec![&data[0]; k];
7610 let shared = result.as_mut_slice() as *mut [&i32];
7611 let combination_op = (data, shared);
7612 let mut counter = 0;
7613 unsafe {
7614 for _ in combination_op.combination(k) {
7615 println!("{:?}", &*shared);
7616 counter += 1;
7617 }
7618 }
7619
7620 assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); // n!/(k!(n-k!))
7621 }
7622
7623 #[test]
7624 fn test_large_combination_fn_k_1() {
7625 let data : &[i32] = &[1, 2, 3, 4, 5, 6];
7626 let k = 1;
7627 let mut counter = 0;
7628 large_combination(data, k, |_result| {
7629 counter += 1;
7630 });
7631
7632 assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); // n!/(k!(n-k!))
7633 }
7634
7635 #[should_panic]
7636 #[test]
7637 fn test_large_combination_fn_k_0() {
7638 let data : &[i32] = &[1, 2, 3, 4, 5, 6];
7639 let k = 0;
7640 let mut counter = 0;
7641 large_combination(data, k, |_result| {
7642 counter += 1;
7643 });
7644
7645 assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); // n!/(k!(n-k!))
7646 }
7647
7648 #[test]
7649 fn test_large_combination_fn_d_eq_k() {
7650 let data : &[i32] = &[1, 2, 3];
7651 let k = 3;
7652 let mut counter = 0;
7653 large_combination(data, k, |_result| {
7654 // println!("{:?}", _result);
7655 counter += 1;
7656 });
7657
7658 assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); // n!/(k!(n-k!))
7659 }
7660
7661 #[test]
7662 fn test_large_combination_fn() {
7663 let data : &[i32] = &[1, 2, 3, 4, 5];
7664 let k = 3;
7665 let mut counter = 0;
7666 large_combination(data, k, |_result| {
7667 // println!("{:?}", _result);
7668 counter += 1;
7669 });
7670
7671 assert_eq!(counter, divide_factorial(data.len(), data.len() - k) / factorial(k) ); // n!/(k!(n-k!))
7672 }
7673
7674 #[test]
7675 fn test_permutation_trait() {
7676 let mut data = [1, 2, 3];
7677 // println!("{:?}", data);
7678 let mut counter = 0;
7679 for permuted in data.permutation() {
7680 println!("test_permutation_trait: {:?}", permuted);
7681 counter += 1;
7682 }
7683
7684 assert_eq!(counter, factorial(data.len()));
7685 }
7686
7687 #[test]
7688 fn test_permutation_trait_cell() {
7689 let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
7690 let mut shared = Rc::new(RefCell::new(data));
7691 let value = Rc::clone(&shared);
7692 let mut counter = 0;
7693 shared.permutation().for_each(|_| {
7694 println!("test_permutation_trait_cell: {:?}", &*value.borrow());
7695 counter += 1;
7696 });
7697
7698 assert_eq!(counter, factorial(value.borrow().len()));
7699 }
7700
7701 #[test]
7702 fn test_permutation_trait_ref() {
7703 let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
7704 let mut shared = data as *mut [i32];
7705 let mut counter = 0;
7706 shared.permutation().for_each(|_| {
7707 println!("test_permutation_trait_ref: {:?}", data);
7708 counter += 1;
7709 });
7710
7711 assert_eq!(counter, factorial(data.len()));
7712 }
7713
7714 #[test]
7715 fn test_k_permutation_primitive() {
7716 let data = [1, 2, 3, 4, 5];
7717 let k = 3;
7718 let mut counter = 0;
7719
7720 data.combination(k).for_each(|mut combination| {
7721 combination.permutation().for_each(|permuted| {
7722 println!("test_k_permutation_primitive: {:?}", permuted);
7723 counter += 1;
7724 });
7725 });
7726
7727 assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
7728 }
7729
7730 #[allow(non_snake_case)]
7731 #[test]
7732 fn test_KPermutation_trait() {
7733 let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
7734 let mut counter = 0;
7735 (&*data, 3usize).permutation().for_each(|_p| {
7736 // println!("{:?}", p);
7737 counter += 1;
7738 });
7739
7740 assert_eq!(counter, divide_factorial(data.len(), data.len() - 3));
7741 }
7742
7743 #[allow(non_snake_case)]
7744 #[test]
7745 fn test_KPermutation_single() {
7746 let data : &mut[i32] = &mut [1, 2, 3, 4, 5];
7747 let mut counter = 0;
7748 let k = 1usize;
7749 (&*data, k).permutation().for_each(|_p| {
7750 println!("{:?}", _p);
7751 counter += 1;
7752 });
7753
7754 assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
7755 }
7756
7757 #[allow(non_snake_case)]
7758 #[test]
7759 fn test_KPermutation_into_cell_trait() {
7760 use std::time::Instant;
7761
7762 let data : &mut[i32] = &mut [1, 2, 3, 4, 5, 6];
7763 let mut counter = 0;
7764 let k = 2;
7765 let mut result : Vec<&i32> = vec![&data[0]; k];
7766 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
7767 let timer = Instant::now();
7768 (&*data, k, Rc::clone(&shared)).permutation().for_each(|_| {
7769 // println!("{:?}", &*shared.borrow());
7770 counter += 1;
7771 });
7772
7773 println!("Total {} combination done in {:?}", counter, timer.elapsed());
7774 assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
7775 }
7776
7777 #[allow(non_snake_case, unused_unsafe)]
7778 #[test]
7779 fn test_KPermutation_into_Ref_trait() {
7780 use std::time::Instant;
7781
7782 let data : &[i32] = &[1, 2, 3, 4, 5];
7783 let mut counter = 0;
7784 let k = 3;
7785 let mut result : Vec<&i32> = vec![&data[0]; k];
7786 let shared = result.as_mut_slice() as *mut [&i32];
7787 let timer = Instant::now();
7788 unsafe {
7789 (data, k, shared).permutation().for_each(|_| {
7790 // println!("{:?}", &*shared);
7791 counter += 1;
7792 });
7793
7794 println!("Total {} combination done in {:?}", counter, timer.elapsed());
7795 assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
7796 }
7797 }
7798
7799 // #[test]
7800 // fn test_lexicographic_combination() {
7801 // let mut x = 7;
7802
7803 // for _ in 0..40 {
7804 // println!("{:0>8b}", x);
7805 // stanford_combination(&mut x);
7806 // }
7807 // }
7808
7809 #[test]
7810 fn test_combination_fn() {
7811 let data = [1, 2, 3, 4, 5];
7812 let r = 3;
7813 let mut counter = 0;
7814
7815 combination(&data, r, |comb| {
7816 println!("{:?}", comb);
7817 counter += 1;
7818 });
7819
7820 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7821 }
7822
7823 #[test]
7824 fn test_combination_fn_single() {
7825 let data = [1];
7826 let r = 1;
7827 let mut counter = 0;
7828
7829 combination(&data, r, |comb| {
7830 println!("{:?}", comb);
7831 counter += 1;
7832 });
7833
7834 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7835 }
7836
7837 #[test]
7838 fn test_combination_fn_bound() {
7839 let data = [1, 2, 3];
7840 let r = 3;
7841 let mut counter = 0;
7842
7843 combination(&data, r, |comb| {
7844 println!("{:?}", comb);
7845 counter += 1;
7846 });
7847
7848 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7849 }
7850
7851 #[test]
7852 fn test_large_combination_cell_fn() {
7853 let data : &mut [i32] = &mut [1, 2, 3, 4, 5];
7854 let r = 3;
7855 let mut counter = 0;
7856 let mut result : Vec<&i32> = vec![&data[0]; r];
7857 let shared : Rc<RefCell<&mut [&i32]>> = Rc::new(RefCell::new(&mut result));
7858
7859 large_combination_cell(&data, r, Rc::clone(&shared), || {
7860 println!("{:?}", shared.borrow());
7861 counter += 1;
7862 });
7863
7864 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7865 }
7866
7867 #[test]
7868 fn test_large_combination_sync_fn() {
7869 let data : &mut [i32] = &mut [1, 2, 3, 4, 5];
7870 let r = 3;
7871 let mut counter = 0;
7872 let result : Vec<&i32> = vec![&data[0]; r];
7873 let shared : Arc<RwLock<Vec<&i32>>> = Arc::new(RwLock::new(result));
7874
7875 large_combination_sync(&data, r, Arc::clone(&shared), || {
7876 println!("{:?}", shared.read().unwrap());
7877 counter += 1;
7878 });
7879
7880 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7881 }
7882
7883 #[test]
7884 fn test_unsafe_combination_fn() {
7885 let data = [1, 2, 3, 4, 5];
7886 let r = 3;
7887 let mut counter = 0;
7888 let mut result = vec![&data[0]; r];
7889 let result_ptr = result.as_mut_slice() as *mut [&usize];
7890
7891 unsafe {
7892 unsafe_combination(&data, r, result_ptr, || {
7893 println!("{:?}", result);
7894 counter += 1;
7895 });
7896 }
7897
7898 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7899 }
7900
7901 #[test]
7902 fn test_combination_cell_fn() {
7903 let data = [1, 2, 3, 4, 5];
7904 let r = 3;
7905 let mut counter = 0;
7906 let mut result = vec![&data[0]; r];
7907 let result_cell = Rc::new(RefCell::new(result.as_mut_slice()));
7908
7909 combination_cell(&data, r, Rc::clone(&result_cell), || {
7910 println!("{:?}", result_cell.borrow());
7911 counter += 1;
7912 });
7913
7914 assert_eq!(counter, divide_factorial(data.len(), data.len() - r) / factorial(r));
7915 }
7916
7917 #[test]
7918 fn test_unsafe_shared_combination_result_fn() {
7919 use std::fmt::Debug;
7920
7921 trait Consumer {
7922 fn consume(&self);
7923 }
7924 struct Worker1<'a, T : 'a> {
7925 data : &'a[&'a T]
7926 }
7927 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
7928 fn consume(&self) {
7929 // println!("Work1 has {:?}", self.data);
7930 self.data.iter().for_each(|_| {});
7931 }
7932 }
7933 struct Worker2<'a, T : 'a> {
7934 data : &'a[&'a T]
7935 }
7936 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
7937 fn consume(&self) {
7938 // println!("Work2 has {:?}", self.data);
7939 self.data.iter().for_each(|_| {});
7940 }
7941 }
7942
7943 unsafe fn start_combination_process<'a>(data : &'a[i32], cur_result : *mut [&'a i32], k : usize, consumers : Vec<Box<dyn Consumer + 'a>>) {
7944 use std::time::Instant;
7945 let timer = Instant::now();
7946 let mut counter = 0;
7947 unsafe_combination(data, k, cur_result, || {
7948 consumers.iter().for_each(|c| {
7949 c.consume();
7950 });
7951 counter += 1;
7952 });
7953 println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
7954 }
7955 let k = 5;
7956 let data = &[1, 2, 3, 4, 5, 6];
7957 let mut result = vec![&data[0]; k];
7958
7959 unsafe {
7960
7961 let shared = result.as_mut_slice() as *mut [&i32];
7962 let worker1 = Worker1 {
7963 data : &result
7964 };
7965 let worker2 = Worker2 {
7966 data : &result
7967 };
7968 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
7969 start_combination_process(data, shared, k, consumers);
7970 }
7971 }
7972
7973 #[test]
7974 fn test_shared_combination_result_fn() {
7975 use std::fmt::Debug;
7976
7977 trait Consumer {
7978 fn consume(&self);
7979 }
7980 struct Worker1<'a, T : 'a> {
7981 data : Rc<RefCell<&'a mut[&'a T]>>
7982 }
7983 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
7984 fn consume(&self) {
7985 // println!("Work1 has {:?}", self.data.borrow());
7986 let result = self.data.borrow();
7987 result.iter().for_each(|_| {});
7988 }
7989 }
7990 struct Worker2<'a, T : 'a> {
7991 data : Rc<RefCell<&'a mut[&'a T]>>
7992 }
7993 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
7994 fn consume(&self) {
7995 // println!("Work2 has {:?}", self.data.borrow());
7996 let result = self.data.borrow();
7997 result.iter().for_each(|_| {});
7998 }
7999 }
8000
8001 fn start_combination_process<'a>(data : &'a[i32], cur_result : Rc<RefCell<&'a mut[&'a i32]>>, k : usize, consumers : Vec<Box<dyn Consumer + 'a>>) {
8002 use std::time::Instant;
8003 let timer = Instant::now();
8004 let mut counter = 0;
8005 combination_cell(data, k, cur_result, || {
8006 consumers.iter().for_each(|c| {
8007 c.consume();
8008 });
8009 counter += 1;
8010 });
8011 println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
8012 }
8013 let k = 4;
8014 let data = &[1, 2, 3, 4, 5, 6, 7];
8015 let mut result = vec![&data[0]; k];
8016 let result_cell = Rc::new(RefCell::new(result.as_mut_slice()));
8017
8018 let worker1 = Worker1 {
8019 data : Rc::clone(&result_cell)
8020 };
8021 let worker2 = Worker2 {
8022 data : Rc::clone(&result_cell)
8023 };
8024 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8025 start_combination_process(data, result_cell, k, consumers);
8026 }
8027
8028 #[test]
8029 fn test_shared_combination_result_sync_fn() {
8030 fn start_combination_process<'a>(data : &'a[i32], cur_result : Arc<RwLock<Vec<&'a i32>>>, k : usize, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
8031 use std::time::Instant;
8032 let timer = Instant::now();
8033 let mut counter = 0;
8034 combination_sync(data, k, cur_result, || {
8035 notifier.iter().for_each(|n| {
8036 n.send(Some(())).unwrap(); // notify every thread that new data available
8037 });
8038
8039 for _ in 0..notifier.len() {
8040 release_recv.recv().unwrap(); // block until all thread reading data notify on read completion
8041 }
8042
8043 counter += 1;
8044 });
8045
8046 notifier.iter().for_each(|n| {n.send(None).unwrap()}); // notify every thread that there'll be no more data.
8047
8048 println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
8049 }
8050 let k = 4;
8051 let data = &[1, 2, 3, 4, 5, 6];
8052 let result = vec![&data[0]; k];
8053 let result_sync = Arc::new(RwLock::new(result));
8054
8055 // workter thread 1
8056 let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
8057 let (main_send, main_recv) = mpsc::sync_channel(0);
8058 let t1_local = main_send.clone();
8059 let t1_dat = Arc::clone(&result_sync);
8060 thread::spawn(move || {
8061 while let Some(_) = t1_recv.recv().unwrap() {
8062 let _result : &Vec<&i32> = &*t1_dat.read().unwrap();
8063 // println!("Thread1: {:?}", _result);
8064 t1_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
8065 }
8066 println!("Thread1 is done");
8067 });
8068
8069 // worker thread 2
8070 let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
8071 let t2_dat = Arc::clone(&result_sync);
8072 let t2_local = main_send.clone();
8073 thread::spawn(move || {
8074 while let Some(_) = t2_recv.recv().unwrap() {
8075 let _result : &Vec<&i32> = &*t2_dat.read().unwrap();
8076 // println!("Thread2: {:?}", _result);
8077 t2_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
8078 }
8079 println!("Thread2 is done");
8080 });
8081
8082 // main thread that generate result
8083 thread::spawn(move || {
8084 start_combination_process(data, result_sync, k, vec![t1_send, t2_send], main_recv);
8085 }).join().unwrap();
8086 }
8087
8088 #[allow(non_snake_case)]
8089 #[test]
8090 fn test_share_result_CombinationIterator_with_thread_fn() {
8091 let k = 3;
8092 let data : &[i32] = &[1, 2, 3, 4, 5];
8093
8094 // workter thread 1
8095 let (t1_send, t1_recv) = mpsc::sync_channel::<Option<Vec<&i32>>>(0);
8096
8097 thread::spawn(move || {
8098 while let Some(c) = t1_recv.recv().unwrap() {
8099 let _result : Vec<&i32> = c;
8100 // println!("Thread1: {:?}", _result);
8101 }
8102 println!("Thread1 is done");
8103 });
8104
8105 // worker thread 2
8106 let (t2_send, t2_recv) = mpsc::sync_channel::<Option<Vec<&i32>>>(0);
8107 thread::spawn(move || {
8108 while let Some(c) = t2_recv.recv().unwrap() {
8109 let _result : Vec<&i32> = c;
8110 // println!("Thread2: {:?}", _result);
8111 }
8112 println!("Thread2 is done");
8113 });
8114
8115 let channels = vec![t1_send, t2_send];
8116 // main thread that generate result
8117 thread::spawn(move || {
8118 use std::time::Instant;
8119 let timer = Instant::now();
8120 let mut counter = 0;
8121
8122 data.combination(k).for_each(|c| {
8123 channels.iter().for_each(|t| {t.send(Some(c.to_owned())).unwrap();});
8124 counter += 1;
8125 });
8126 channels.iter().for_each(|t| {t.send(None).unwrap()});
8127 println!("Done {} combinations in {:?}", counter, timer.elapsed());
8128 }).join().unwrap();
8129 }
8130
8131 #[test]
8132 fn test_shared_combination_result_iterator_alike() {
8133 use std::fmt::Debug;
8134 use std::time::Instant;
8135
8136 trait Consumer {
8137 fn consume(&self);
8138 }
8139 struct Worker1<'a, T : 'a> {
8140 data : Rc<RefCell<&'a mut[&'a T]>>
8141 }
8142 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8143 fn consume(&self) {
8144 // println!("Work1 has {:?}", self.data.borrow());
8145 let result = self.data.borrow();
8146 result.iter().for_each(|_| {});
8147 }
8148 }
8149 struct Worker2<'a, T : 'a> {
8150 data : Rc<RefCell<&'a mut[&'a T]>>
8151 }
8152 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8153 fn consume(&self) {
8154 // println!("Work2 has {:?}", self.data.borrow());
8155 let result = self.data.borrow();
8156 result.iter().for_each(|_| {});
8157 }
8158 }
8159 let k = 4;
8160 let data = &[1, 2, 3, 4, 5, 6, 7];
8161 let mut result = vec![&data[0]; k];
8162 let result_cell = Rc::new(RefCell::new(result.as_mut_slice()));
8163
8164 let worker1 = Worker1 {
8165 data : Rc::clone(&result_cell)
8166 };
8167 let worker2 = Worker2 {
8168 data : Rc::clone(&result_cell)
8169 };
8170 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8171 let gosper = GosperCombinationCellIter::new(data, k, result_cell);
8172 let timer = Instant::now();
8173 let mut counter = 0;
8174
8175 for _ in gosper {
8176 consumers.iter().for_each(|c| {c.consume()});
8177 counter += 1;
8178 }
8179
8180 println!("Total {} combinations done in {:?}", counter, timer.elapsed());
8181 }
8182
8183 #[test]
8184 fn test_unsafe_cartesian_product_shared_result() {
8185 use std::fmt::Debug;
8186
8187 trait Consumer {
8188 fn consume(&self);
8189 }
8190 struct Worker1<'a, T : 'a> {
8191 data : &'a[&'a T]
8192 }
8193 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8194 fn consume(&self) {
8195 println!("Work1 has {:?}", self.data);
8196 }
8197 }
8198 struct Worker2<'a, T : 'a> {
8199 data : &'a[&'a T]
8200 }
8201 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8202 fn consume(&self) {
8203 println!("Work2 has {:?}", self.data);
8204 }
8205 }
8206
8207 unsafe fn start_cartesian_product_process<'a>(data : &'a[&'a[i32]], cur_result : *mut [&'a i32], consumers : Vec<Box<dyn Consumer + 'a>>) {
8208 unsafe_cartesian_product(data, cur_result, || {
8209 consumers.iter().for_each(|c| {
8210 c.consume();
8211 })
8212 });
8213 }
8214
8215 let data : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6]];
8216 let mut result = vec![&data[0][0]; data.len()];
8217
8218 unsafe {
8219
8220 let shared = result.as_mut_slice() as *mut [&i32];
8221 let worker1 = Worker1 {
8222 data : &result
8223 };
8224 let worker2 = Worker2 {
8225 data : &result
8226 };
8227 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8228 start_cartesian_product_process(data, shared, consumers);
8229 }
8230 }
8231
8232 #[allow(unused)]
8233 #[test]
8234 fn test_unsafe_self_cartesian_product_shared_result() {
8235 use std::fmt::Debug;
8236
8237 trait Consumer {
8238 fn consume(&self);
8239 }
8240 struct Worker1<'a, T : 'a> {
8241 data : &'a[&'a T]
8242 }
8243 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8244 fn consume(&self) {
8245 // println!("Work1 has {:?}", self.data);
8246 }
8247 }
8248 struct Worker2<'a, T : 'a> {
8249 data : &'a[&'a T]
8250 }
8251 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8252 fn consume(&self) {
8253 // println!("Work2 has {:?}", self.data);
8254 }
8255 }
8256
8257 unsafe fn start_cartesian_product_process<'a>(data : &'a[i32], n : usize, cur_result : *mut [&'a i32], consumers : Vec<Box<dyn Consumer + 'a>>) {
8258 use std::time::Instant;
8259 let timer = Instant::now();
8260 let mut counter = 0;
8261 unsafe_self_cartesian_product(data, n, cur_result, || {
8262 consumers.iter().for_each(|c| {
8263 c.consume();
8264 });
8265 counter += 1;
8266 });
8267
8268 println!("start_cartesian_product_process: {} products in {:?}", counter, timer.elapsed());
8269 }
8270
8271 let data : &[i32] = &[1, 2, 3];
8272 let n = 3;
8273 let mut result = vec![&data[0]; n];
8274
8275 unsafe {
8276
8277 let shared = result.as_mut_slice() as *mut [&i32];
8278 let worker1 = Worker1 {
8279 data : &result
8280 };
8281 let worker2 = Worker2 {
8282 data : &result
8283 };
8284 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8285 start_cartesian_product_process(data, n, shared, consumers);
8286 }
8287 }
8288
8289 #[test]
8290 fn test_cartesian_product_shared_result_fn() {
8291 use std::fmt::Debug;
8292
8293 trait Consumer {
8294 fn consume(&self);
8295 }
8296 struct Worker1<'a, T : 'a> {
8297 data : Rc<RefCell<&'a mut[&'a T]>>
8298 }
8299 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8300 fn consume(&self) {
8301 println!("Work1 has {:?}", self.data);
8302 }
8303 }
8304 struct Worker2<'a, T : 'a> {
8305 data : Rc<RefCell<&'a mut[&'a T]>>
8306 }
8307 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8308 fn consume(&self) {
8309 println!("Work2 has {:?}", self.data);
8310 }
8311 }
8312
8313 fn start_cartesian_product_process<'a>(data : &'a[&'a[i32]], cur_result : Rc<RefCell<&'a mut [&'a i32]>>, consumers : Vec<Box<dyn Consumer + 'a>>) {
8314 cartesian_product_cell(data, cur_result, || {
8315 consumers.iter().for_each(|c| {
8316 c.consume();
8317 })
8318 });
8319 }
8320
8321 let data : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6]];
8322 let mut result = vec![&data[0][0]; data.len()];
8323
8324 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
8325 let worker1 = Worker1 {
8326 data : Rc::clone(&shared)
8327 };
8328 let worker2 = Worker2 {
8329 data : Rc::clone(&shared)
8330 };
8331 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8332 start_cartesian_product_process(data, shared, consumers);
8333 }
8334
8335 #[allow(unused)]
8336 #[test]
8337 fn test_self_cartesian_product_shared_result_fn() {
8338 use std::fmt::Debug;
8339
8340 trait Consumer {
8341 fn consume(&self);
8342 }
8343 struct Worker1<'a, T : 'a> {
8344 data : Rc<RefCell<&'a mut[&'a T]>>
8345 }
8346 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8347 fn consume(&self) {
8348 println!("Work1 has {:?}", self.data);
8349 }
8350 }
8351 struct Worker2<'a, T : 'a> {
8352 data : Rc<RefCell<&'a mut[&'a T]>>
8353 }
8354 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8355 fn consume(&self) {
8356 println!("Work2 has {:?}", self.data);
8357 }
8358 }
8359
8360 fn start_cartesian_product_process<'a>(data : &'a[i32], n : usize, cur_result : Rc<RefCell<&'a mut [&'a i32]>>, consumers : Vec<Box<dyn Consumer + 'a>>) {
8361 self_cartesian_product_cell(data, n, cur_result, || {
8362 consumers.iter().for_each(|c| {
8363 c.consume();
8364 })
8365 });
8366 }
8367
8368 let data : &[i32] = &[1, 2, 3];
8369 let n = 3;
8370 let mut result = vec![&data[0]; n];
8371
8372 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
8373 let worker1 = Worker1 {
8374 data : Rc::clone(&shared)
8375 };
8376 let worker2 = Worker2 {
8377 data : Rc::clone(&shared)
8378 };
8379 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8380 start_cartesian_product_process(data, n, shared, consumers);
8381
8382 }
8383
8384 #[allow(non_snake_case)]
8385 #[test]
8386 fn test_CartesianProduct_iterator_alike_shared_result() {
8387 use std::fmt::Debug;
8388
8389 trait Consumer {
8390 fn consume(&self);
8391 }
8392 struct Worker1<'a, T : 'a> {
8393 data : Rc<RefCell<&'a mut[&'a T]>>
8394 }
8395 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8396 fn consume(&self) {
8397 println!("Work1 has {:?}", self.data);
8398 }
8399 }
8400 struct Worker2<'a, T : 'a> {
8401 data : Rc<RefCell<&'a mut[&'a T]>>
8402 }
8403 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8404 fn consume(&self) {
8405 println!("Work2 has {:?}", self.data);
8406 }
8407 }
8408
8409 fn start_cartesian_product_process<'a>(data : &'a[&'a[i32]], cur_result : Rc<RefCell<&'a mut [&'a i32]>>, consumers : Vec<Box<dyn Consumer + 'a>>) {
8410 let cart = CartesianProductCellIter::new(data, cur_result);
8411 for _ in cart {
8412 consumers.iter().for_each(|c| {
8413 c.consume();
8414 })
8415 };
8416 }
8417
8418 let data : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6]];
8419 let mut result = vec![&data[0][0]; data.len()];
8420
8421 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
8422 let worker1 = Worker1 {
8423 data : Rc::clone(&shared)
8424 };
8425 let worker2 = Worker2 {
8426 data : Rc::clone(&shared)
8427 };
8428 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8429 start_cartesian_product_process(data, shared, consumers);
8430
8431 }
8432 #[test]
8433 fn test_shared_cartesian_product_result_sync_fn() {
8434 fn start_cartesian_product_process<'a>(data : &'a[&[i32]], cur_result : Arc<RwLock<Vec<&'a i32>>>, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
8435 use std::time::Instant;
8436 let timer = Instant::now();
8437 let mut counter = 0;
8438 cartesian_product_sync(data, cur_result, || {
8439 notifier.iter().for_each(|n| {
8440 n.send(Some(())).unwrap(); // notify every thread that new data available
8441 });
8442
8443 for _ in 0..notifier.len() {
8444 release_recv.recv().unwrap(); // block until all thread reading data notify on read completion
8445 }
8446
8447 counter += 1;
8448 });
8449
8450 notifier.iter().for_each(|n| {n.send(None).unwrap()}); // notify every thread that there'll be no more data.
8451
8452 println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
8453 }
8454 let k = 3;
8455 let data : &[&[i32]]= &[&[1, 2, 3], &[4, 5], &[6, 7, 8, 9, 10]];
8456 let result = vec![&data[0][0]; k];
8457 let result_sync = Arc::new(RwLock::new(result));
8458
8459 // workter thread 1
8460 let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
8461 let (main_send, main_recv) = mpsc::sync_channel(0);
8462 let t1_local = main_send.clone();
8463 let t1_dat = Arc::clone(&result_sync);
8464 thread::spawn(move || {
8465 while let Some(_) = t1_recv.recv().unwrap() {
8466 let _result : &Vec<&i32> = &*t1_dat.read().unwrap();
8467 // println!("Thread1: {:?}", _result);
8468 t1_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
8469 }
8470 println!("Thread1 is done");
8471 });
8472
8473 // worker thread 2
8474 let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
8475 let t2_dat = Arc::clone(&result_sync);
8476 let t2_local = main_send.clone();
8477 thread::spawn(move || {
8478 while let Some(_) = t2_recv.recv().unwrap() {
8479 let _result : &Vec<&i32> = &*t2_dat.read().unwrap();
8480 // println!("Thread2: {:?}", _result);
8481 t2_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
8482 }
8483 println!("Thread2 is done");
8484 });
8485
8486 // main thread that generate result
8487 thread::spawn(move || {
8488 start_cartesian_product_process(data, result_sync, vec![t1_send, t2_send], main_recv);
8489 }).join().unwrap();
8490 }
8491
8492 #[allow(non_snake_case)]
8493 #[test]
8494 fn test_shared_CartesianProduct_result_sync() {
8495 let data : &[&[i32]]= &[&[1, 2, 3], &[4, 5], &[6, 7, 8, 9]];
8496 let result = vec![&data[0][0]; data.len()];
8497 let result_sync = Arc::new(RwLock::new(result));
8498
8499 // workter thread 1
8500 let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
8501 let t1_dat = Arc::clone(&result_sync);
8502 thread::spawn(move || {
8503 while let Some(_) = t1_recv.recv().unwrap() {
8504 let _result : &Vec<&i32> = &*t1_dat.read().unwrap();
8505 println!("Thread1: {:?}", _result);
8506 }
8507 println!("Thread1 is done");
8508 });
8509
8510 // worker thread 2
8511 let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
8512 let t2_dat = Arc::clone(&result_sync);
8513 thread::spawn(move || {
8514 while let Some(_) = t2_recv.recv().unwrap() {
8515 let _result : &Vec<&i32> = &*t2_dat.read().unwrap();
8516 println!("Thread2: {:?}", _result);
8517 }
8518 println!("Thread2 is done");
8519 });
8520
8521 let consumers = vec![t1_send, t2_send];
8522 // main thread that generate result
8523 thread::spawn(move || {
8524 use std::time::Instant;
8525 let cart = CartesianProductIterator::new(data);
8526 let mut counter = 0;
8527 let timer = Instant::now();
8528
8529 cart.into_iter().for_each(|_| {
8530 consumers.iter().for_each(|c| {
8531 c.send(Some(())).unwrap();
8532 });
8533 counter += 1;
8534 });
8535
8536 consumers.iter().for_each(|c| {
8537 c.send(None).unwrap(); // Explicitly terminate all workers
8538 });
8539
8540 println!("Done {} products in {:?}", counter, timer.elapsed());
8541 }).join().unwrap();
8542 }
8543
8544 #[allow(non_snake_case)]
8545 #[test]
8546 fn test_share_CartesianProductIterator_result_to_thread() {
8547 let data : &[&[i32]]= &[&[1, 2, 3], &[4, 5], &[6, 7, 8, 9]];
8548
8549 // workter thread 1
8550 let (t1_send, t1_recv) = mpsc::channel::<Option<Vec<&i32>>>();
8551 thread::spawn(move || {
8552 while let Some(p) = t1_recv.recv().unwrap() {
8553 println!("Thread1: {:?}", p);
8554 }
8555 println!("Thread1 is done");
8556 });
8557
8558 // worker thread 2
8559 let (t2_send, t2_recv) = mpsc::channel::<Option<Vec<&i32>>>();
8560 thread::spawn(move || {
8561 while let Some(p) = t2_recv.recv().unwrap() {
8562 println!("Thread2: {:?}", p);
8563 }
8564 println!("Thread2 is done");
8565 });
8566
8567 let consumers = vec![t1_send, t2_send];
8568 // main thread that generate result
8569 thread::spawn(move || {
8570 use std::time::Instant;
8571 let cart = CartesianProductIterator::new(data);
8572 let mut counter = 0;
8573 let timer = Instant::now();
8574
8575 cart.into_iter().for_each(|p| {
8576 println!("{:?}", p);
8577 consumers.iter().for_each(|c| {
8578 c.send(Some(p.to_owned())).unwrap();
8579 });
8580 counter += 1;
8581 });
8582
8583 consumers.iter().for_each(|c| {
8584 c.send(None).unwrap(); // Explicitly terminate all workers
8585 });
8586
8587 println!("Main: Done {} products in {:?}", counter, timer.elapsed());
8588 }).join().unwrap();
8589 }
8590
8591 #[test]
8592 fn test_unsafe_shared_k_permutation_result_fn() {
8593 use std::fmt::Debug;
8594
8595 trait Consumer {
8596 fn consume(&self);
8597 }
8598 struct Worker1<'a, T : 'a> {
8599 data : &'a[&'a T]
8600 }
8601 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8602 fn consume(&self) {
8603 println!("Work1 has {:?}", self.data);
8604 }
8605 }
8606 struct Worker2<'a, T : 'a> {
8607 data : &'a[&'a T]
8608 }
8609 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8610 fn consume(&self) {
8611 println!("Work2 has {:?}", self.data);
8612 }
8613 }
8614
8615 unsafe fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : *mut [&'a i32], k : usize, consumers : Vec<Box<dyn Consumer + 'a>>) {
8616 unsafe_k_permutation(data, k, cur_result, || {
8617 consumers.iter().for_each(|c| {
8618 c.consume();
8619 })
8620 });
8621 }
8622 let k = 3;
8623 let data = &[1, 2, 3, 4, 5];
8624 let mut result = vec![&data[0]; k];
8625
8626 unsafe {
8627
8628 let shared = result.as_mut_slice() as *mut [&i32];
8629 let worker1 = Worker1 {
8630 data : &result
8631 };
8632 let worker2 = Worker2 {
8633 data : &result
8634 };
8635 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8636 start_k_permutation_process(data, shared, k, consumers);
8637 }
8638 }
8639
8640 #[test]
8641 fn test_shared_k_permutation_result_fn() {
8642 use std::fmt::Debug;
8643
8644 trait Consumer {
8645 fn consume(&self);
8646 }
8647 struct Worker1<'a, T : 'a> {
8648 data : Rc<RefCell<&'a mut[&'a T]>>
8649 }
8650 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8651 fn consume(&self) {
8652 println!("Work1 has {:?}", self.data.borrow());
8653 }
8654 }
8655 struct Worker2<'a, T : 'a> {
8656 data : Rc<RefCell<&'a mut[&'a T]>>
8657 }
8658 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8659 fn consume(&self) {
8660 println!("Work2 has {:?}", self.data.borrow());
8661 }
8662 }
8663
8664 fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : Rc<RefCell<&'a mut [&'a i32]>>, k : usize, consumers : Vec<Box<dyn Consumer + 'a>>) {
8665 use std::time::Instant;
8666 let timer = Instant::now();
8667 let mut counter = 0;
8668 k_permutation_cell(data, k, cur_result, || {
8669 consumers.iter().for_each(|c| {
8670 c.consume();
8671 });
8672 counter += 1;
8673 });
8674
8675 println!("Total {} permutation done in {:?}", counter, timer.elapsed());
8676 }
8677 let k = 3;
8678 let data = &[1, 2, 3, 4, 5];
8679 let mut result = vec![&data[0]; k];
8680 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
8681
8682 let worker1 = Worker1 {
8683 data : Rc::clone(&shared)
8684 };
8685 let worker2 = Worker2 {
8686 data : Rc::clone(&shared)
8687 };
8688 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8689 start_k_permutation_process(data, shared, k, consumers);
8690 }
8691
8692 #[allow(non_snake_case)]
8693 #[test]
8694 fn test_shared_KPermutation_result() {
8695 use std::time::Instant;
8696 use std::fmt::Debug;
8697
8698 trait Consumer {
8699 fn consume(&self);
8700 }
8701 struct Worker1<'a, T : 'a> {
8702 data : Rc<RefCell<&'a mut[&'a T]>>
8703 }
8704 impl<'a, T : 'a + Debug> Consumer for Worker1<'a, T> {
8705 fn consume(&self) {
8706 println!("Work1 has {:?}", self.data.borrow());
8707 }
8708 }
8709 struct Worker2<'a, T : 'a> {
8710 data : Rc<RefCell<&'a mut[&'a T]>>
8711 }
8712 impl<'a, T : 'a + Debug> Consumer for Worker2<'a, T> {
8713 fn consume(&self) {
8714 println!("Work2 has {:?}", self.data.borrow());
8715 }
8716 }
8717
8718 let k = 3;
8719 let data = &[1, 2, 3, 4, 5];
8720 let mut result = vec![&data[0]; k];
8721 let shared = Rc::new(RefCell::new(result.as_mut_slice()));
8722
8723 let worker1 = Worker1 {
8724 data : Rc::clone(&shared)
8725 };
8726 let worker2 = Worker2 {
8727 data : Rc::clone(&shared)
8728 };
8729 let consumers : Vec<Box<dyn Consumer>> = vec![Box::new(worker1), Box::new(worker2)];
8730
8731 let kperm = KPermutationCellIter::new(data, k, shared);
8732 let timer = Instant::now();
8733 let mut counter = 0;
8734 for _ in kperm {
8735 consumers.iter().for_each(|c| {c.consume();});
8736 counter += 1;
8737 }
8738
8739 println!("Total {} permutation done in {:?}", counter, timer.elapsed());
8740 assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
8741 }
8742
8743 #[test]
8744 fn test_shared_k_permutation_sync_fn() {
8745 fn start_k_permutation_process<'a>(data : &'a[i32], cur_result : Arc<RwLock<Vec<&'a i32>>>, k : usize, notifier : Vec<SyncSender<Option<()>>>, release_recv : Receiver<()>) {
8746 use std::time::Instant;
8747 let timer = Instant::now();
8748 let mut counter = 0;
8749 k_permutation_sync(data, k, cur_result, || {
8750 notifier.iter().for_each(|n| {
8751 n.send(Some(())).unwrap(); // notify every thread that new data available
8752 });
8753
8754 for _ in 0..notifier.len() {
8755 release_recv.recv().unwrap(); // block until all thread reading data notify on read completion
8756 }
8757
8758 counter += 1;
8759 });
8760
8761 notifier.iter().for_each(|n| {n.send(None).unwrap()}); // notify every thread that there'll be no more data.
8762
8763 println!("Done {} combinations with 2 workers in {:?}", counter, timer.elapsed());
8764 }
8765 let k = 4;
8766 let data = &[1, 2, 3, 4, 5, 6];
8767 let result = vec![&data[0]; k];
8768 let result_sync = Arc::new(RwLock::new(result));
8769
8770 // workter thread 1
8771 let (t1_send, t1_recv) = mpsc::sync_channel::<Option<()>>(0);
8772 let (main_send, main_recv) = mpsc::sync_channel(0);
8773 let t1_local = main_send.clone();
8774 let t1_dat = Arc::clone(&result_sync);
8775 thread::spawn(move || {
8776 while let Some(_) = t1_recv.recv().unwrap() {
8777 let _result : &Vec<&i32> = &*t1_dat.read().unwrap();
8778 // println!("Thread1: {:?}", _result);
8779 t1_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
8780 }
8781 println!("Thread1 is done");
8782 });
8783
8784 // worker thread 2
8785 let (t2_send, t2_recv) = mpsc::sync_channel::<Option<()>>(0);
8786 let t2_dat = Arc::clone(&result_sync);
8787 let t2_local = main_send.clone();
8788 thread::spawn(move || {
8789 while let Some(_) = t2_recv.recv().unwrap() {
8790 let _result : &Vec<&i32> = &*t2_dat.read().unwrap();
8791 // println!("Thread2: {:?}", _result);
8792 t2_local.send(()).unwrap(); // notify generator thread that reference is no longer neeed.
8793 }
8794 println!("Thread2 is done");
8795 });
8796
8797 // main thread that generate result
8798 thread::spawn(move || {
8799 start_k_permutation_process(data, result_sync, k, vec![t1_send, t2_send], main_recv);
8800 }).join().unwrap();
8801 }
8802
8803 #[allow(non_snake_case)]
8804 #[test]
8805 fn test_share_result_KPermutation_iterator_sync() {
8806 let k = 3;
8807 let data : &[i32] = &[1, 2, 3, 4, 5];
8808
8809 // workter thread 1
8810 let (t1_send, t1_recv) = mpsc::sync_channel::<Option<Vec<&i32>>>(0);
8811
8812 thread::spawn(move || {
8813 while let Some(c) = t1_recv.recv().unwrap() {
8814 let _result : Vec<&i32> = c;
8815 println!("Thread1: {:?}", _result);
8816 }
8817 println!("Thread1 is done");
8818 });
8819
8820 // worker thread 2
8821 let (t2_send, t2_recv) = mpsc::sync_channel::<Option<Vec<&i32>>>(0);
8822 thread::spawn(move || {
8823 while let Some(c) = t2_recv.recv().unwrap() {
8824 let _result : Vec<&i32> = c;
8825 println!("Thread2: {:?}", _result);
8826 }
8827 println!("Thread2 is done");
8828 });
8829
8830 let channels = vec![t1_send, t2_send];
8831 // main thread that generate result
8832 thread::spawn(move || {
8833 use std::time::Instant;
8834 let timer = Instant::now();
8835 let mut counter = 0;
8836 let kperm = KPermutationIterator::new(data, k);
8837
8838 kperm.into_iter().for_each(|c| {
8839 channels.iter().for_each(|t| {t.send(Some(c.to_owned())).unwrap();});
8840 counter += 1;
8841 });
8842 channels.iter().for_each(|t| {t.send(None).unwrap()});
8843 println!("Done {} combinations in {:?}", counter, timer.elapsed());
8844 assert_eq!(counter, divide_factorial(data.len(), data.len() - k));
8845 }).join().unwrap();
8846 }
8847
8848 #[test]
8849 fn test_unsafe_cartesian_product() {
8850 use std::time::Instant;
8851 let set = (1..4).map(|item| item).collect::<Vec<u64>>();
8852 let mut data = Vec::<&[u64]>::new();
8853 for _ in 0..3 {
8854 data.push(&set);
8855 }
8856
8857 let mut counter = 0;
8858 let mut result = vec![&data[0][0]; data.len()];
8859 let result_ptr = result.as_mut_slice() as *mut [&u64];
8860 let timer = Instant::now();
8861
8862 unsafe {
8863 unsafe_cartesian_product(&data, result_ptr, || {
8864 // println!("{:?}", product);
8865 counter += 1;
8866 });
8867 }
8868
8869 println!("Total {} product done in {:?}", counter, timer.elapsed());
8870 }
8871
8872 #[allow(unused)]
8873 #[test]
8874 fn test_unsafe_k_permutation() {
8875 use std::time::{Instant};
8876 let data = [1, 2, 3, 4, 5];
8877 let k = 3;
8878 let mut counter = 0;
8879 let mut result = vec![&data[0]; k];
8880 let timer = Instant::now();
8881 unsafe {
8882 unsafe_k_permutation(&data, k, result.as_mut_slice() as *mut [&usize], || {
8883 // uncomment line below to print all k-permutation
8884 println!("test_unsafe_k_permutation: {}:{:?}", counter, result);
8885 counter += 1;
8886 });
8887 }
8888
8889 println!("test_unsafe_k_permutation: Total {} permutations done in {:?}", counter, timer.elapsed());
8890 assert_eq!(divide_factorial(data.len(), data.len() - k), counter);
8891 }
8892
8893 #[test]
8894 fn test_tldr_case() {
8895 let domains : &[&[i32]] = &[&[1, 2], &[3, 4, 5], &[6], &[7, 8], &[9, 10, 11]];
8896 domains.cart_prod().for_each(|cp| {
8897 // each cp will be &[&i32] with length equals to domains.len() which in this case 5
8898
8899 // It's k-permutation of size 3 over data.
8900 cp.combination(3).for_each(|mut c| { // need mut
8901
8902 // start permute the 3-combination
8903 c.permutation().for_each(|p| {
8904 // print each permutation of the 3-combination.
8905 println!("TLDR: {:?}", p);
8906 });
8907
8908 // It'll print the last 3-permutation again because permutation permute the value in place.
8909 println!("TLDR: {:?}", c);
8910 })
8911 });
8912 }
8913
8914 #[test]
8915 fn test_x_permutation() {
8916 let data = vec![1, 2, 3, 4];
8917 let mut counter = 0;
8918
8919 x_permutation(&data, |_| true, |p| {
8920 println!("{:?}", p);
8921 counter += 1;
8922 });
8923
8924 assert_eq!(factorial(data.len()), counter);
8925 }
8926
8927 #[test]
8928 fn test_x_permutation_cell() {
8929 let data = vec![1, 2, 3, 4];
8930 let mut result = vec![&data[0]; data.len()];
8931 let share = Rc::new(RefCell::new(result.as_mut_slice()));
8932 let mut counter = 0;
8933
8934 x_permutation_cell(&data, Rc::clone(&share), |_| true, || {
8935 println!("{:?}", &*share.borrow());
8936 counter += 1;
8937 });
8938
8939 assert_eq!(factorial(data.len()), counter);
8940 }
8941
8942 #[test]
8943 fn test_x_permutation_sync() {
8944 let data = vec![1, 2, 3, 4];
8945 let result = vec![&data[0]; data.len()];
8946 let share = Arc::new(RwLock::new(result));
8947 let mut counter = 0;
8948
8949 x_permutation_sync(&data, Arc::clone(&share), |_| true, || {
8950 println!("{:?}", &*share.read().unwrap());
8951 counter += 1;
8952 });
8953
8954 assert_eq!(factorial(data.len()), counter);
8955 }
8956
8957 #[test]
8958 fn test_unsafe_x_permutation() {
8959 let data = vec![1u8, 2, 3, 4];
8960 let mut result = vec![&data[0]; data.len()];
8961 let share = result.as_mut_slice() as *mut [&u8];
8962 let mut counter = 0;
8963
8964 unsafe {
8965 unsafe_x_permutation(&data, share, |_| true, || {
8966 println!("{:?}", result);
8967 counter += 1;
8968 });
8969 }
8970
8971 assert_eq!(factorial(data.len()), counter);
8972 }
8973
8974 #[test]
8975 fn test_x_permutation_restricted() {
8976 let data : Vec<u8> = vec![1, 2, 3, 4];
8977 let mut counter = 0;
8978
8979 x_permutation(&data, |f| {
8980 *f[0] != 1u8 // filter all permutation that start with 1
8981 }, |p| {
8982 println!("{:?}", p);
8983 counter += 1;
8984 });
8985
8986 assert_eq!(factorial(data.len()) - factorial(data.len() - 1), counter);
8987 }
8988
8989 #[test]
8990 #[ignore]
8991 fn test_lex_family() {
8992 let data : &[&[u8]] = &[&[1, 2, 3], &[4, 5], &[6, 7], &[8, 9], &[10]];
8993 let k = 3;
8994
8995 data.cart_prod().for_each(|cp| {
8996 // lexicographically ordered cartesian product in `cp`
8997 LargeCombinationIterator::new(&cp, k).for_each(|co| {
8998 // lexicographically ordered combination of length 3
8999 x_permutation(&co, |_| true, |p| {
9000 // lexicographically ordered permutation
9001 println!("{:?}", p);
9002 });
9003 });
9004 });
9005
9006 // generate k-permutation that first element is even number out of
9007 // cartesian product.
9008 data.cart_prod().for_each(|cp| {
9009 // lexicographically ordered cartesian product in `cp`
9010 LargeCombinationIterator::new(&cp, k).for_each(|co| {
9011 // lexicographically ordered combination of length 3
9012 x_permutation(
9013 &co,
9014 |v| ***v[0] & 1 != 1,
9015 |p|
9016 {
9017 // lexicographically ordered permutation
9018 println!("{:?}", p);
9019 });
9020 });
9021 });
9022 }
9023
9024 #[test]
9025 #[ignore]
9026 fn compare_gosper_custom_fn() {
9027 use std::time::Instant;
9028 let data : Vec<i32> = (0..30i32).map(|i| {i}).collect();
9029 let r = 20;
9030 let mut counter = 0;
9031 let timer = Instant::now();
9032 combination(&data, r, |_c| {counter += 1});
9033 println!("Stanford comb {} combination done in {:?}", counter, timer.elapsed());
9034 counter = 0;
9035 let timer = Instant::now();
9036 large_combination(&data, r, |_c| {counter += 1});
9037 println!("Custom comb {} combination done in {:?}", counter, timer.elapsed());
9038 }
9039
9040 #[test]
9041 #[ignore]
9042 fn compare_gosper_custom_iter() {
9043 use std::time::Instant;
9044 let data : Vec<i32> = (0..30i32).map(|i| {i}).collect();
9045 let r = 20;
9046 let mut counter = 0;
9047 let timer = Instant::now();
9048 let stanford = GosperCombinationIterator::new(&data, r);
9049 stanford.into_iter().for_each(|_c| {counter += 1});
9050 println!("Stanford comb {} combination done in {:?}", counter, timer.elapsed());
9051 counter = 0;
9052 let timer = Instant::now();
9053 let mut lc = LargeCombinationIterator::new(&data, r);
9054 lc.iter().for_each(|_c| {counter += 1});
9055 println!("Custom comb {} combination done in {:?}", counter, timer.elapsed());
9056 }
9057
9058 #[test]
9059 #[ignore]
9060 fn compare_gosper_custom_cell_iter() {
9061 use std::time::Instant;
9062 let data : Vec<i32> = (0..30i32).map(|i| {i}).collect();
9063 let r = 20;
9064 let mut result = vec![&data[0]; r];
9065 let share : Rc<RefCell<&mut[&i32]>> = Rc::new(RefCell::new(&mut result));
9066 let mut counter = 0;
9067 let timer = Instant::now();
9068 let stanford = GosperCombinationCellIter::new(&data, r, Rc::clone(&share));
9069 stanford.into_iter().for_each(|_c| {counter += 1});
9070 println!("Stanford comb {} combination done in {:?}", counter, timer.elapsed());
9071 counter = 0;
9072 let timer = Instant::now();
9073 let mut lc = LargeCombinationCellIter::new(&data, r, Rc::clone(&share));
9074 lc.iter().for_each(|_c| {counter += 1});
9075 println!("Custom comb {} combination done in {:?}", counter, timer.elapsed());
9076 }
9077
9078 #[test]
9079 #[ignore]
9080 fn compare_gosper_custom_ref_iter() {
9081 use std::time::Instant;
9082 let data : Vec<i32> = (0..30i32).map(|i| {i}).collect();
9083 let r = 20;
9084 let mut result = vec![&data[0]; r];
9085 let share = result.as_mut_slice() as *mut [&i32];
9086
9087 unsafe {
9088 let mut counter = 0;
9089 let timer = Instant::now();
9090 let stanford = GosperCombinationRefIter::new(&data, r, share);
9091 stanford.into_iter().for_each(|_c| {counter += 1});
9092 println!("Stanford comb {} combination done in {:?}", counter, timer.elapsed());
9093 counter = 0;
9094 let timer = Instant::now();
9095 let mut lc = LargeCombinationRefIter::new(&data, r, share);
9096 lc.iter().for_each(|_c| {counter += 1});
9097 println!("Custom comb {} combination done in {:?}", counter, timer.elapsed());
9098 }
9099 }
9100
9101 #[test]
9102 #[ignore]
9103 fn bench_heap_fn() {
9104 use std::time::Instant;
9105 let mut data : Vec<i32> = (0..10i32).map(|i| {i}).collect();
9106 let timer = Instant::now();
9107 let mut counter = 0;
9108
9109 heap_permutation(data.as_mut_slice(), |_p| {counter += 1});
9110
9111 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
9112 }
9113
9114 #[test]
9115 #[ignore]
9116 fn bench_heap_iter() {
9117 use std::time::Instant;
9118 let mut data : Vec<i32> = (0..10i32).map(|i| {i}).collect();
9119 let timer = Instant::now();
9120 let mut counter = 0;
9121
9122 data.permutation().for_each(|_p| {counter += 1});
9123
9124 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
9125 }
9126
9127 #[test]
9128 #[ignore]
9129 fn bench_k_perm_fn() {
9130 use std::time::Instant;
9131
9132 let data : Vec<i32> = (0..13i32).map(|i| {i}).collect();
9133 let timer = Instant::now();
9134 let mut counter = 0;
9135
9136 k_permutation(data.as_slice(), 7, |_p| {counter += 1});
9137
9138 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
9139 }
9140
9141 #[test]
9142 #[ignore]
9143 fn bench_k_perm_iter() {
9144 use std::time::Instant;
9145
9146 let data : Vec<i32> = (0..13i32).map(|i| {i}).collect();
9147 let timer = Instant::now();
9148 let mut counter = 0;
9149
9150 (data.as_slice(), 7usize).permutation().for_each(|_p| {counter += 1});
9151
9152 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
9153 }
9154
9155 #[test]
9156 #[ignore]
9157 fn bench_cart_fn() {
9158 use std::time::Instant;
9159 let domain : Vec<i32> = (0..5i32).map(|i| {i}).collect();
9160 let domains : Vec<&[i32]> = (0..10).map(|_| domain.as_slice()).collect();
9161 let timer = Instant::now();
9162 let mut counter = 0;
9163
9164 cartesian_product(domains.as_slice(), |_p| {counter += 1});
9165
9166 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
9167 }
9168
9169 #[test]
9170 #[ignore]
9171 fn bench_cart_iter() {
9172 use std::time::Instant;
9173 let domain : Vec<i32> = (0..5i32).map(|i| {i}).collect();
9174 let domains : Vec<&[i32]> = (0..10).map(|_| domain.as_slice()).collect();
9175 let timer = Instant::now();
9176 let mut counter = 0;
9177
9178 domains.as_slice().cart_prod().for_each(|_p| {counter += 1});
9179
9180 println!("Total {} permutations done in {:?}", counter, timer.elapsed());
9181 }
9182
9183 #[test]
9184 #[ignore]
9185 fn bench_x_perm_st_fn() { // st mean single thread
9186 use std::time::Instant;
9187
9188 let mut data : Vec<u8> = (0..13u8).map(|v| v).collect();
9189 let mut counter = 0;
9190 let timer = Instant::now();
9191
9192 x_permutation(&data, |_| true, |_p| {
9193 counter += 1;
9194 });
9195
9196 println!("Done {} x_permutation in {:?}", counter, timer.elapsed());
9197 counter = 0;
9198 let timer = Instant::now();
9199
9200 heap_permutation(&mut data, |_p| {
9201 counter += 1;
9202 });
9203
9204 println!("Done {} heap_permutation in {:?}", counter, timer.elapsed());
9205 }
9206
9207 #[test]
9208 #[ignore]
9209 fn bench_x_perm_mt_fn() { // st mean single thread
9210 use std::time::{Duration, Instant};
9211
9212 let mut data : Vec<u8> = (0..13u8).map(|v| v).collect();
9213 let threads = 3usize;
9214 let chunk = data.len() / threads; // split data into 3 threads.
9215 let complete_count = Arc::new(RwLock::new(0u64));
9216 let total_counter = Arc::new(RwLock::new(0u64));
9217 for i in 0..threads {
9218 let u_bound = match i {
9219 j if j == threads - 1 => data.len() as u8, // last thread do all the rest
9220 _ => (chunk * (i + 1)) as u8
9221 };
9222 let l_bound = (chunk * i) as u8;
9223 println!("thread{}: {}-{}", i, l_bound, u_bound);
9224 let perm = get_permutation_for(&data, data.len(), l_bound as usize).unwrap();
9225 let t_dat : Vec<u8> = perm.iter().map(|v| **v).collect(); // need to move to each thread
9226 let t_counter = Arc::clone(&complete_count); // thread completed count
9227 let loc_counter = Arc::clone(&total_counter); // count number of permutation
9228 thread::spawn(move || {
9229 let mut counter = 0u64;
9230 x_permutation(&t_dat, |v| {
9231 *v[0] >= l_bound && *v[0] < u_bound
9232 }, |_p| {
9233 counter += 1;
9234 });
9235
9236 *loc_counter.write().unwrap() += counter;
9237 println!("Done {} in local thread", counter);
9238 *t_counter.write().unwrap() += 1;
9239 });
9240 }
9241
9242 let main = thread::spawn(move || {
9243 let timer = Instant::now();
9244 loop {
9245 if *complete_count.read().unwrap() != (threads as u64) {
9246 thread::sleep(Duration::from_millis(100));
9247 } else {
9248 println!("Done {} x_permutation {} threads in {:?}", &*total_counter.read().unwrap(), threads, timer.elapsed());
9249 break;
9250 }
9251 }
9252 });
9253
9254 main.join().unwrap();
9255
9256 let mut counter = 0u64;
9257 let timer = Instant::now();
9258
9259 heap_permutation(&mut data, |_p| {
9260 counter += 1;
9261 });
9262
9263 println!("Done {} heap_permutation in {:?}", counter, timer.elapsed());
9264 }
9265
9266 #[test]
9267 #[allow(unused)]
9268 fn test_case_15() {
9269 // https://github.com/NattapongSiri/permutator/issues/15
9270 let mut a = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
9271 for mut _c in a.combination(2) {
9272 }
9273 }
9274
9275 #[test]
9276 #[allow(unused)]
9277 fn test_case_16() {
9278 // https://github.com/NattapongSiri/permutator/issues/16
9279 let data = [0, 1];
9280 // expected
9281 for x in CartesianProductIterator::new(&[&data[..]; 3][..]) {
9282 // println!("{:?}", x);
9283 }
9284 // panics
9285 for x in SelfCartesianProductIterator::new(&data, 3) {
9286 // println!("{:?}", x);
9287 }
9288 }
9289}