@@ -307,6 +307,7 @@ pub struct ElementSwaps {
307
307
sdir : ~[ SizeDirection ] ,
308
308
/// If true, emit the last swap that returns the sequence to initial state
309
309
emit_reset : bool ,
310
+ swaps_made : uint ,
310
311
}
311
312
312
313
impl ElementSwaps {
@@ -319,7 +320,8 @@ impl ElementSwaps {
319
320
emit_reset : true ,
320
321
sdir : range ( 0 , length)
321
322
. map ( |i| SizeDirection { size : i, dir : Neg } )
322
- . collect :: < ~[ _ ] > ( )
323
+ . collect :: < ~[ _ ] > ( ) ,
324
+ swaps_made : 0
323
325
}
324
326
}
325
327
}
@@ -358,16 +360,30 @@ impl Iterator<(uint, uint)> for ElementSwaps {
358
360
x. dir = match x. dir { Pos => Neg , Neg => Pos } ;
359
361
}
360
362
}
363
+ self . swaps_made += 1 ;
361
364
Some ( ( i, j) )
362
365
} ,
363
- None => if self . emit_reset && self . sdir . len ( ) > 1 {
366
+ None => if self . emit_reset {
364
367
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 }
369
378
}
370
379
}
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
+ }
371
387
}
372
388
373
389
/// An Iterator that uses `ElementSwaps` to iterate through
@@ -388,13 +404,19 @@ impl<T: Clone> Iterator<~[T]> for Permutations<T> {
388
404
fn next ( & mut self ) -> Option < ~[ T ] > {
389
405
match self . swaps . next ( ) {
390
406
None => None ,
407
+ Some ( ( 0 , 0 ) ) => Some ( self . v . clone ( ) ) ,
391
408
Some ( ( a, b) ) => {
392
409
let elt = self . v . clone ( ) ;
393
410
self . v . swap ( a, b) ;
394
411
Some ( elt)
395
412
}
396
413
}
397
414
}
415
+
416
+ #[ inline]
417
+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
418
+ self . swaps . size_hint ( )
419
+ }
398
420
}
399
421
400
422
/// An iterator over the (overlapping) slices of length `size` within
@@ -2767,19 +2789,33 @@ mod tests {
2767
2789
{
2768
2790
let v: [ int , ..0 ] = [ ] ;
2769
2791
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( ) ) ) ;
2770
2796
assert_eq ! ( it. next( ) , None ) ;
2771
2797
}
2772
2798
{
2773
2799
let v = [ "Hello" . to_owned ( ) ] ;
2774
2800
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( ) ) ) ;
2775
2805
assert_eq ! ( it. next( ) , None ) ;
2776
2806
}
2777
2807
{
2778
2808
let v = [ 1 , 2 , 3 ] ;
2779
2809
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 ) ;
2780
2813
assert_eq ! ( it. next( ) , Some ( ~[ 1 , 2 , 3 ] ) ) ;
2781
2814
assert_eq ! ( it. next( ) , Some ( ~[ 1 , 3 , 2 ] ) ) ;
2782
2815
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 ) ;
2783
2819
assert_eq ! ( it. next( ) , Some ( ~[ 3 , 2 , 1 ] ) ) ;
2784
2820
assert_eq ! ( it. next( ) , Some ( ~[ 2 , 3 , 1 ] ) ) ;
2785
2821
assert_eq ! ( it. next( ) , Some ( ~[ 2 , 1 , 3 ] ) ) ;
@@ -2789,10 +2825,15 @@ mod tests {
2789
2825
// check that we have N! permutations
2790
2826
let v = [ 'A' , 'B' , 'C' , 'D' , 'E' , 'F' ] ;
2791
2827
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 {
2793
2831
amt += 1 ;
2794
2832
}
2833
+ assert_eq ! ( amt, it. swaps. swaps_made) ;
2834
+ assert_eq ! ( amt, min_size) ;
2795
2835
assert_eq ! ( amt, 2 * 3 * 4 * 5 * 6 ) ;
2836
+ assert_eq ! ( amt, max_opt. unwrap( ) ) ;
2796
2837
}
2797
2838
}
2798
2839
0 commit comments