darklua_core/process/utils/
permutator.rs1#[derive(Debug)]
2pub struct Permutator<I> {
3 original_producer: I,
4 current_producers: Vec<I>,
5 root: String,
6}
7
8impl<I: Iterator + Clone> Permutator<I> {
9 pub fn new(producer: I) -> Self {
10 Self {
11 original_producer: producer.clone(),
12 current_producers: vec![producer],
13 root: String::new(),
14 }
15 }
16
17 fn new_producer(&self) -> I {
18 self.original_producer.clone()
19 }
20}
21
22impl<I: Iterator<Item = char> + Clone> Iterator for Permutator<I> {
23 type Item = String;
24
25 fn next(&mut self) -> Option<String> {
26 let next_char = self
27 .current_producers
28 .last_mut()
29 .and_then(|producer| producer.next());
30
31 if let Some(value) = next_char {
32 let mut string = self.root.clone();
33 string.push(value);
34 Some(string)
35 } else {
36 let mut count_pop = 1;
37 self.current_producers.pop();
38
39 while let Some(previous_producer) = self.current_producers.last_mut() {
40 self.root.pop();
41 if let Some(next_root_char) = previous_producer.next() {
42 self.root.push(next_root_char);
43 count_pop -= 1;
44 break;
45 } else {
46 self.current_producers.pop();
47 count_pop += 1;
48 }
49 }
50
51 for _ in 0..count_pop {
52 let mut new_producer = self.new_producer();
53 self.root.push(new_producer.next().unwrap());
54 self.current_producers.push(new_producer);
55 }
56
57 self.current_producers.push(self.original_producer.clone());
58
59 self.next()
60 }
61 }
62}
63
64#[cfg(test)]
65mod test {
66 use super::*;
67 use std::convert::TryInto;
68
69 #[test]
70 fn produce_all_permutations_with_single_char() {
71 let mut permutate = Permutator::new("ab".chars());
72
73 assert_eq!(permutate.next().unwrap(), "a");
74 assert_eq!(permutate.next().unwrap(), "b");
75 }
76
77 #[test]
78 fn produce_all_permutations_with_two_chars() {
79 let mut permutate = Permutator::new("ab".chars());
80
81 assert_eq!(permutate.next().unwrap(), "a");
82 assert_eq!(permutate.next().unwrap(), "b");
83 assert_eq!(permutate.next().unwrap(), "aa");
84 assert_eq!(permutate.next().unwrap(), "ab");
85 assert_eq!(permutate.next().unwrap(), "ba");
86 assert_eq!(permutate.next().unwrap(), "bb");
87 }
88
89 #[test]
90 fn produce_all_permutations_with_three_chars() {
91 let mut permutate = Permutator::new("ab".chars());
92
93 for _ in 0..(2 + 2) ^ 2 {
94 permutate.next();
95 }
96
97 assert_eq!(permutate.next().unwrap(), "aaa");
98 assert_eq!(permutate.next().unwrap(), "aab");
99 assert_eq!(permutate.next().unwrap(), "aba");
100 assert_eq!(permutate.next().unwrap(), "abb");
101 assert_eq!(permutate.next().unwrap(), "baa");
102 assert_eq!(permutate.next().unwrap(), "bab");
103 assert_eq!(permutate.next().unwrap(), "bba");
104 assert_eq!(permutate.next().unwrap(), "bbb");
105 }
106
107 #[test]
108 fn produce_only_first_char_permutations() {
109 let char_set = "01";
110 let set_length = char_set.len();
111
112 let mut permutate = Permutator::new(char_set.chars());
113
114 for length in 1..9 {
115 assert_eq!(permutate.next().unwrap(), char_set[0..1].repeat(length));
116
117 for _ in 0..set_length.pow(length.try_into().unwrap()) - 1 {
118 assert!(permutate.next().is_some());
119 }
120 }
121 }
122}