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