From 2618cd3639922f4cc4ba3bd65a71e4ea3b78c051 Mon Sep 17 00:00:00 2001 From: philipp Date: Wed, 6 Sep 2023 22:15:13 +0200 Subject: [PATCH 1/2] Simplify Permutations (1.1) move impl Permutations This simply moves code around so that the subsequent diff is simpler. --- src/permutations.rs | 76 ++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/permutations.rs b/src/permutations.rs index cfdb06b2a..4f96d8f68 100644 --- a/src/permutations.rs +++ b/src/permutations.rs @@ -83,6 +83,44 @@ pub fn permutations(iter: I, k: usize) -> Permutations { } } +impl Permutations +where + I: Iterator, + I::Item: Clone +{ + fn advance(&mut self) { + let &mut Permutations { ref mut vals, ref mut state } = self; + + *state = match *state { + PermutationState::StartUnknownLen { k } => { + PermutationState::OngoingUnknownLen { k, min_n: k } + } + PermutationState::OngoingUnknownLen { k, min_n } => { + if vals.get_next() { + PermutationState::OngoingUnknownLen { k, min_n: min_n + 1 } + } else { + let n = min_n; + let prev_iteration_count = n - k + 1; + let mut complete_state = CompleteState::Start { n, k }; + + // Advance the complete-state iterator to the correct point + for _ in 0..(prev_iteration_count + 1) { + complete_state.advance(); + } + + PermutationState::Complete(complete_state) + } + } + PermutationState::Complete(ref mut state) => { + state.advance(); + + return; + } + PermutationState::Empty => { return; } + }; + } +} + impl Iterator for Permutations where I: Iterator, @@ -159,44 +197,6 @@ where } } -impl Permutations -where - I: Iterator, - I::Item: Clone -{ - fn advance(&mut self) { - let &mut Permutations { ref mut vals, ref mut state } = self; - - *state = match *state { - PermutationState::StartUnknownLen { k } => { - PermutationState::OngoingUnknownLen { k, min_n: k } - } - PermutationState::OngoingUnknownLen { k, min_n } => { - if vals.get_next() { - PermutationState::OngoingUnknownLen { k, min_n: min_n + 1 } - } else { - let n = min_n; - let prev_iteration_count = n - k + 1; - let mut complete_state = CompleteState::Start { n, k }; - - // Advance the complete-state iterator to the correct point - for _ in 0..(prev_iteration_count + 1) { - complete_state.advance(); - } - - PermutationState::Complete(complete_state) - } - } - PermutationState::Complete(ref mut state) => { - state.advance(); - - return; - } - PermutationState::Empty => { return; } - }; - } -} - impl CompleteState { fn advance(&mut self) { *self = match *self { From 21608b5249c9b3fcf0d493addb180d27d40f5592 Mon Sep 17 00:00:00 2001 From: philipp Date: Wed, 6 Sep 2023 22:15:13 +0200 Subject: [PATCH 2/2] Simplify Permutations (1.2) inline Permutations::advance This at least makes clear why the panic! in Permutations::next cannot happen. --- src/permutations.rs | 67 ++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/src/permutations.rs b/src/permutations.rs index 4f96d8f68..92ba7e6a3 100644 --- a/src/permutations.rs +++ b/src/permutations.rs @@ -83,44 +83,6 @@ pub fn permutations(iter: I, k: usize) -> Permutations { } } -impl Permutations -where - I: Iterator, - I::Item: Clone -{ - fn advance(&mut self) { - let &mut Permutations { ref mut vals, ref mut state } = self; - - *state = match *state { - PermutationState::StartUnknownLen { k } => { - PermutationState::OngoingUnknownLen { k, min_n: k } - } - PermutationState::OngoingUnknownLen { k, min_n } => { - if vals.get_next() { - PermutationState::OngoingUnknownLen { k, min_n: min_n + 1 } - } else { - let n = min_n; - let prev_iteration_count = n - k + 1; - let mut complete_state = CompleteState::Start { n, k }; - - // Advance the complete-state iterator to the correct point - for _ in 0..(prev_iteration_count + 1) { - complete_state.advance(); - } - - PermutationState::Complete(complete_state) - } - } - PermutationState::Complete(ref mut state) => { - state.advance(); - - return; - } - PermutationState::Empty => { return; } - }; - } -} - impl Iterator for Permutations where I: Iterator, @@ -129,10 +91,35 @@ where type Item = Vec; fn next(&mut self) -> Option { - self.advance(); + { + let &mut Permutations { ref mut vals, ref mut state } = self; + match *state { + PermutationState::StartUnknownLen { k } => { + *state = PermutationState::OngoingUnknownLen { k, min_n: k }; + }, + PermutationState::OngoingUnknownLen { k, min_n } => { + if vals.get_next() { + *state = PermutationState::OngoingUnknownLen { k, min_n: min_n + 1 }; + } else { + let n = min_n; + let prev_iteration_count = n - k + 1; + let mut complete_state = CompleteState::Start { n, k }; - let &mut Permutations { ref vals, ref state } = self; + // Advance the complete-state iterator to the correct point + for _ in 0..(prev_iteration_count + 1) { + complete_state.advance(); + } + *state = PermutationState::Complete(complete_state); + } + }, + PermutationState::Complete(ref mut state) => { + state.advance(); + }, + PermutationState::Empty => {}, + }; + } + let &mut Permutations { ref vals, ref state } = self; match *state { PermutationState::StartUnknownLen { .. } => panic!("unexpected iterator state"), PermutationState::OngoingUnknownLen { k, min_n } => {