1
1
use alloc:: boxed:: Box ;
2
2
use alloc:: vec:: Vec ;
3
3
use std:: fmt;
4
- use std:: iter:: once;
5
4
use std:: iter:: FusedIterator ;
6
5
7
6
use super :: lazy_buffer:: LazyBuffer ;
@@ -39,7 +38,8 @@ enum PermutationState<Idx: PoolIndex> {
39
38
/// All values from the iterator are known so `n` is known.
40
39
Loaded {
41
40
indices : Box < [ usize ] > ,
42
- cycles : Box < [ usize ] > ,
41
+ cycles : Box < [ usize ] > , // TODO Should be Idx::Item<usize>
42
+ k : Idx :: Length , // TODO Should be inferred from cycles
43
43
} ,
44
44
/// No permutation left to generate.
45
45
End ,
66
66
I : Iterator ,
67
67
I :: Item : Clone ,
68
68
{
69
- type Item = Vec < I :: Item > ;
69
+ type Item = Idx :: Item < I :: Item > ;
70
70
71
71
fn next ( & mut self ) -> Option < Self :: Item > {
72
72
let Self { vals, state } = self ;
@@ -82,14 +82,18 @@ where
82
82
}
83
83
* state = PermutationState :: Buffered { k, min_n : k. value ( ) } ;
84
84
}
85
- Some ( vals[ 0 ..k . value ( ) ] . to_vec ( ) )
85
+ Some ( Idx :: from_fn ( k , |i| vals[ i ] . clone ( ) ) )
86
86
}
87
- PermutationState :: Buffered { ref k, min_n } => {
87
+ PermutationState :: Buffered { k, min_n } => {
88
88
if vals. get_next ( ) {
89
- let item = ( 0 ..k. value ( ) - 1 )
90
- . chain ( once ( * min_n) )
91
- . map ( |i| vals[ i] . clone ( ) )
92
- . collect ( ) ;
89
+ // TODO This is ugly. Maybe working on indices is better?
90
+ let item = Idx :: from_fn ( * k, |i| {
91
+ vals[ if i==k. value ( ) -1 {
92
+ * min_n
93
+ } else {
94
+ i
95
+ } ] . clone ( )
96
+ } ) ;
93
97
* min_n += 1 ;
94
98
Some ( item)
95
99
} else {
@@ -104,18 +108,17 @@ where
104
108
return None ;
105
109
}
106
110
}
107
- let item = vals . get_at ( & indices[ 0 ..k . value ( ) ] ) ;
108
- * state = PermutationState :: Loaded { indices, cycles } ;
111
+ let item = Idx :: from_fn ( * k , |i| vals [ indices[ i ] ] . clone ( ) ) ;
112
+ * state = PermutationState :: Loaded { indices, cycles, k : * k } ;
109
113
Some ( item)
110
114
}
111
115
}
112
- PermutationState :: Loaded { indices, cycles } => {
116
+ PermutationState :: Loaded { indices, cycles, k } => {
113
117
if advance ( indices, cycles) {
114
118
* state = PermutationState :: End ;
115
119
return None ;
116
120
}
117
- let k = cycles. len ( ) ;
118
- Some ( vals. get_at ( & indices[ 0 ..k] ) )
121
+ Some ( Idx :: from_fn ( * k, |i| vals[ indices[ i] ] . clone ( ) ) )
119
122
}
120
123
PermutationState :: End => None ,
121
124
}
@@ -178,6 +181,7 @@ impl<Idx: PoolIndex> PermutationState<Idx> {
178
181
Self :: Loaded {
179
182
ref indices,
180
183
ref cycles,
184
+ k : _,
181
185
} => {
182
186
let count = cycles. iter ( ) . enumerate ( ) . try_fold ( 0usize , |acc, ( i, & c) | {
183
187
acc. checked_mul ( indices. len ( ) - i)
0 commit comments