4 use super::lazy_buffer
::LazyBuffer
;
6 /// An iterator adaptor that iterates through all the `k`-permutations of the
7 /// elements from an iterator.
9 /// See [`.permutations()`](../trait.Itertools.html#method.permutations) for
11 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
12 pub struct Permutations
<I
: Iterator
> {
14 state
: PermutationState
,
17 impl<I
> Clone
for Permutations
<I
>
18 where I
: Clone
+ Iterator
,
21 clone_fields
!(vals
, state
);
24 #[derive(Clone, Debug)]
25 enum PermutationState
{
33 Complete(CompleteState
),
37 #[derive(Clone, Debug)]
49 enum CompleteStateRemaining
{
54 impl<I
> fmt
::Debug
for Permutations
<I
>
55 where I
: Iterator
+ fmt
::Debug
,
58 debug_fmt_fields
!(Permutations
, vals
, state
);
61 pub fn permutations
<I
: Iterator
>(iter
: I
, k
: usize) -> Permutations
<I
> {
62 let mut vals
= LazyBuffer
::new(iter
);
65 // Special case, yields single empty vec; `n` is irrelevant
66 let state
= PermutationState
::Complete(CompleteState
::Start { n: 0, k: 0 }
);
74 let mut enough_vals
= true;
76 while vals
.len() < k
{
83 let state
= if enough_vals
{
84 PermutationState
::StartUnknownLen { k }
86 PermutationState
::Empty
95 impl<I
> Iterator
for Permutations
<I
>
100 type Item
= Vec
<I
::Item
>;
102 fn next(&mut self) -> Option
<Self::Item
> {
105 let &mut Permutations { ref vals, ref state }
= self;
108 &PermutationState
::StartUnknownLen { .. }
=> panic
!("unexpected iterator state"),
109 &PermutationState
::OngoingUnknownLen { k, min_n }
=> {
110 let latest_idx
= min_n
- 1;
111 let indices
= (0..(k
- 1)).chain(once(latest_idx
));
113 Some(indices
.map(|i
| vals
[i
].clone()).collect())
115 &PermutationState
::Complete(CompleteState
::Start { .. }
) => None
,
116 &PermutationState
::Complete(CompleteState
::Ongoing { ref indices, ref cycles }
) => {
117 let k
= cycles
.len();
119 Some(indices
[0..k
].iter().map(|&i
| vals
[i
].clone()).collect())
121 &PermutationState
::Empty
=> None
125 fn count(self) -> usize {
126 let Permutations { vals, state }
= self;
128 fn from_complete(complete_state
: CompleteState
) -> usize {
129 match complete_state
.remaining() {
130 CompleteStateRemaining
::Known(count
) => count
,
131 CompleteStateRemaining
::Overflow
=> {
132 panic
!("Iterator count greater than usize::MAX");
138 PermutationState
::StartUnknownLen { k }
=> {
139 let n
= vals
.len() + vals
.it
.count();
140 let complete_state
= CompleteState
::Start { n, k }
;
142 from_complete(complete_state
)
144 PermutationState
::OngoingUnknownLen { k, min_n }
=> {
145 let prev_iteration_count
= min_n
- k
+ 1;
146 let n
= vals
.len() + vals
.it
.count();
147 let complete_state
= CompleteState
::Start { n, k }
;
149 from_complete(complete_state
) - prev_iteration_count
151 PermutationState
::Complete(state
) => from_complete(state
),
152 PermutationState
::Empty
=> 0
156 fn size_hint(&self) -> (usize, Option
<usize>) {
158 PermutationState
::StartUnknownLen { .. }
|
159 PermutationState
::OngoingUnknownLen { .. }
=> (0, None
), // TODO can we improve this lower bound?
160 PermutationState
::Complete(ref state
) => match state
.remaining() {
161 CompleteStateRemaining
::Known(count
) => (count
, Some(count
)),
162 CompleteStateRemaining
::Overflow
=> (::std
::usize::MAX
, None
)
164 PermutationState
::Empty
=> (0, Some(0))
169 impl<I
> Permutations
<I
>
174 fn advance(&mut self) {
175 let &mut Permutations { ref mut vals, ref mut state }
= self;
177 *state
= match state
{
178 &mut PermutationState
::StartUnknownLen { k }
=> {
179 PermutationState
::OngoingUnknownLen { k, min_n: k }
181 &mut PermutationState
::OngoingUnknownLen { k, min_n }
=> {
183 PermutationState
::OngoingUnknownLen { k, min_n: min_n + 1 }
186 let prev_iteration_count
= n
- k
+ 1;
187 let mut complete_state
= CompleteState
::Start { n, k }
;
189 // Advance the complete-state iterator to the correct point
190 for _
in 0..(prev_iteration_count
+ 1) {
191 complete_state
.advance();
194 PermutationState
::Complete(complete_state
)
197 &mut PermutationState
::Complete(ref mut state
) => {
202 &mut PermutationState
::Empty
=> { return; }
208 fn advance(&mut self) {
210 &mut CompleteState
::Start { n, k }
=> {
211 let indices
= (0..n
).collect();
212 let cycles
= ((n
- k
)..n
).rev().collect();
214 CompleteState
::Ongoing
{
219 &mut CompleteState
::Ongoing { ref mut indices, ref mut cycles }
=> {
220 let n
= indices
.len();
221 let k
= cycles
.len();
223 for i
in (0..k
).rev() {
225 cycles
[i
] = n
- i
- 1;
227 let to_push
= indices
.remove(i
);
228 indices
.push(to_push
);
230 let swap_index
= n
- cycles
[i
];
231 indices
.swap(i
, swap_index
);
238 CompleteState
::Start { n, k }
243 fn remaining(&self) -> CompleteStateRemaining
{
244 use self::CompleteStateRemaining
::{Known, Overflow}
;
247 &CompleteState
::Start { n, k }
=> {
252 let count
: Option
<usize> = (n
- k
+ 1..n
+ 1).fold(Some(1), |acc
, i
| {
253 acc
.and_then(|acc
| acc
.checked_mul(i
))
257 Some(count
) => Known(count
),
261 &CompleteState
::Ongoing { ref indices, ref cycles }
=> {
262 let mut count
: usize = 0;
264 for (i
, &c
) in cycles
.iter().enumerate() {
265 let radix
= indices
.len() - i
;
266 let next_count
= count
.checked_mul(radix
)
267 .and_then(|count
| count
.checked_add(c
));
269 count
= match next_count
{
270 Some(count
) => count
,
271 None
=> { return Overflow; }