combination/
combine.rs

1use crate::select_index;
2
3fn __wrap(tgt: &Vec<usize>, size: usize) -> Vec<(Vec<usize>, usize)> {
4    let mut res: Vec<(Vec<usize>, usize)> = Vec::new();
5
6    if size < 1 {
7        return res;
8    }
9    if size == 1 {
10        for i in 0..tgt.len() {
11            res.push((vec![tgt[i]], i));
12        }
13        return res;
14    }
15
16    let temp = __wrap(tgt, size - 1);
17    for item in temp {
18        let (presize_arr, index) = item;
19        if index < tgt.len() {
20            for j in (index + 1)..tgt.len() {
21                let mut presize_arr_copy = presize_arr.clone();
22                presize_arr_copy.push(tgt[j]);
23                res.push((presize_arr_copy, j));
24            }
25        }
26    }
27
28    res
29}
30
31pub fn index(size: usize, combine_len: usize) -> Vec<Vec<usize>> {
32    let list = (0..size).into_iter().collect();
33    let mut result: Vec<Vec<usize>> = Vec::new();
34    if size < combine_len {
35        return result;
36    }
37    let temp = __wrap(&list, combine_len);
38    for i in temp {
39        result.push(i.0);
40    }
41    result
42}
43
44/// Get combination data from a vec
45///
46/// * for example
47/// ``` rust
48/// use combination::*;
49/// let val = combine::from_vec_at(&vec![10, 20, 30, 40], 2);
50/// for item in val {
51///     println!("{:?}", item);
52/// }
53/// ```
54///
55/// * and will get:
56///
57///```text
58/// [10, 20]
59/// [10, 30]
60/// [10, 40]
61/// [20, 30]
62/// [20, 40]
63/// [30, 40]
64///```
65pub fn from_vec_at<T: Clone>(tgt: &Vec<T>, size: usize) -> Vec<Vec<T>> {
66    let mut res: Vec<Vec<T>> = Vec::new();
67    let temp = index(tgt.len(), size);
68    for item in &temp {
69        let temp = select_index(&tgt, item);
70        res.push(temp);
71    }
72    res
73}
74
75/// Get all combination result from a vec
76///
77/// * for example
78/// ``` rust
79/// use combination::*;
80/// let val = combine::from_vec(&vec![10, 20, 30]);
81/// for item in val {
82///     println!("{:?}", item);
83/// }
84/// ```
85///
86/// * and will get:
87///
88///```text
89/// [10]
90/// [20]
91/// [30]
92/// [10, 20]
93/// [10, 30]
94/// [20, 30]
95/// [10, 20, 30]
96///```
97pub fn from_vec<T: Clone>(list: &Vec<T>) -> Vec<Vec<T>> {
98    let mut res: Vec<Vec<T>> = Vec::new();
99
100    (0..list.len()).for_each(|n| from_vec_at(&list, n).into_iter().for_each(|v| res.push(v)));
101    res.push(list.clone());
102    res
103}
104
105pub trait Combine<T: Clone> {
106    fn combine(&self) -> Vec<Vec<T>>;
107    fn combine_at(&self, size: usize) -> Vec<Vec<T>>;
108}
109
110impl<T: Clone> Combine<T> for Vec<T> {
111    fn combine(&self) -> Vec<Vec<T>> {
112        from_vec(self)
113    }
114
115    fn combine_at(&self, size: usize) -> Vec<Vec<T>> {
116        from_vec_at(self, size)
117    }
118}