@@ -307,6 +307,7 @@ pub struct ElementSwaps {
307307 sdir : ~[ SizeDirection ] ,
308308 /// If true, emit the last swap that returns the sequence to initial state
309309 emit_reset : bool ,
310+ swaps_made : uint ,
310311}
311312
312313impl ElementSwaps {
@@ -319,7 +320,8 @@ impl ElementSwaps {
319320 emit_reset : true ,
320321 sdir : range ( 0 , length)
321322 . map ( |i| SizeDirection { size : i, dir : Neg } )
322- . collect :: < ~[ _ ] > ( )
323+ . collect :: < ~[ _ ] > ( ) ,
324+ swaps_made : 0
323325 }
324326 }
325327}
@@ -358,16 +360,30 @@ impl Iterator<(uint, uint)> for ElementSwaps {
358360 x. dir = match x. dir { Pos => Neg , Neg => Pos } ;
359361 }
360362 }
363+ self . swaps_made += 1 ;
361364 Some ( ( i, j) )
362365 } ,
363- None => if self . emit_reset && self . sdir . len ( ) > 1 {
366+ None => if self . emit_reset {
364367 self . emit_reset = false ;
365- Some ( ( 0 , 1 ) )
366- } else {
367- None
368- }
368+ if self . sdir . len ( ) > 1 {
369+ // The last swap
370+ self . swaps_made += 1 ;
371+ Some ( ( 0 , 1 ) )
372+ } else {
373+ // Vector is of the form [] or [x], and the only permutation is itself
374+ self . swaps_made += 1 ;
375+ Some ( ( 0 , 0 ) )
376+ }
377+ } else { None }
369378 }
370379 }
380+
381+ #[ inline]
382+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
383+ // For a vector of size n, there are exactly n! permutations.
384+ let n = range ( 2 , self . sdir . len ( ) + 1 ) . product ( ) ;
385+ ( n - self . swaps_made , Some ( n - self . swaps_made ) )
386+ }
371387}
372388
373389/// An Iterator that uses `ElementSwaps` to iterate through
@@ -388,13 +404,19 @@ impl<T: Clone> Iterator<~[T]> for Permutations<T> {
388404 fn next ( & mut self ) -> Option < ~[ T ] > {
389405 match self . swaps . next ( ) {
390406 None => None ,
407+ Some ( ( 0 , 0 ) ) => Some ( self . v . clone ( ) ) ,
391408 Some ( ( a, b) ) => {
392409 let elt = self . v . clone ( ) ;
393410 self . v . swap ( a, b) ;
394411 Some ( elt)
395412 }
396413 }
397414 }
415+
416+ #[ inline]
417+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
418+ self . swaps . size_hint ( )
419+ }
398420}
399421
400422/// An iterator over the (overlapping) slices of length `size` within
@@ -2767,19 +2789,33 @@ mod tests {
27672789 {
27682790 let v: [ int , ..0 ] = [ ] ;
27692791 let mut it = v. permutations ( ) ;
2792+ let ( min_size, max_opt) = it. size_hint ( ) ;
2793+ assert_eq ! ( min_size, 1 ) ;
2794+ assert_eq ! ( max_opt. unwrap( ) , 1 ) ;
2795+ assert_eq ! ( it. next( ) , Some ( v. as_slice( ) . to_owned( ) ) ) ;
27702796 assert_eq ! ( it. next( ) , None ) ;
27712797 }
27722798 {
27732799 let v = [ "Hello" . to_owned ( ) ] ;
27742800 let mut it = v. permutations ( ) ;
2801+ let ( min_size, max_opt) = it. size_hint ( ) ;
2802+ assert_eq ! ( min_size, 1 ) ;
2803+ assert_eq ! ( max_opt. unwrap( ) , 1 ) ;
2804+ assert_eq ! ( it. next( ) , Some ( v. as_slice( ) . to_owned( ) ) ) ;
27752805 assert_eq ! ( it. next( ) , None ) ;
27762806 }
27772807 {
27782808 let v = [ 1 , 2 , 3 ] ;
27792809 let mut it = v. permutations ( ) ;
2810+ let ( min_size, max_opt) = it. size_hint ( ) ;
2811+ assert_eq ! ( min_size, 3 * 2 ) ;
2812+ assert_eq ! ( max_opt. unwrap( ) , 3 * 2 ) ;
27802813 assert_eq ! ( it. next( ) , Some ( ~[ 1 , 2 , 3 ] ) ) ;
27812814 assert_eq ! ( it. next( ) , Some ( ~[ 1 , 3 , 2 ] ) ) ;
27822815 assert_eq ! ( it. next( ) , Some ( ~[ 3 , 1 , 2 ] ) ) ;
2816+ let ( min_size, max_opt) = it. size_hint ( ) ;
2817+ assert_eq ! ( min_size, 3 ) ;
2818+ assert_eq ! ( max_opt. unwrap( ) , 3 ) ;
27832819 assert_eq ! ( it. next( ) , Some ( ~[ 3 , 2 , 1 ] ) ) ;
27842820 assert_eq ! ( it. next( ) , Some ( ~[ 2 , 3 , 1 ] ) ) ;
27852821 assert_eq ! ( it. next( ) , Some ( ~[ 2 , 1 , 3 ] ) ) ;
@@ -2789,10 +2825,15 @@ mod tests {
27892825 // check that we have N! permutations
27902826 let v = [ 'A' , 'B' , 'C' , 'D' , 'E' , 'F' ] ;
27912827 let mut amt = 0 ;
2792- for _perm in v. permutations ( ) {
2828+ let mut it = v. permutations ( ) ;
2829+ let ( min_size, max_opt) = it. size_hint ( ) ;
2830+ for _perm in it {
27932831 amt += 1 ;
27942832 }
2833+ assert_eq ! ( amt, it. swaps. swaps_made) ;
2834+ assert_eq ! ( amt, min_size) ;
27952835 assert_eq ! ( amt, 2 * 3 * 4 * 5 * 6 ) ;
2836+ assert_eq ! ( amt, max_opt. unwrap( ) ) ;
27962837 }
27972838 }
27982839
0 commit comments