#!/usr/bin/perl -w use strict; # Here are some stubs so you can test my code. # Replace this with a Fisher Yates shuffle: sub PermuteList { my $av= shift @_; print "Not shuffling ( $av->[0] .. $av->[-1] )\n"; } # Replace these with your own code: sub GetPopulation { return( 100..(99+$ARGV[0]) ); } sub ProcessSample { print "( @_ )\n"; } sub Lcd { my( $x, $y )= @_; while( 1 ) { if( $y < $x ) { ( $x, $y )= ( $y, $x ); } if( $x == 0 ) { return $y; } $y %= $x; } } sub GenNextSample { my( $size, @list )= @_; my $step = @list; my( $start, $offset ); return sub { while( 1 ) { if( @list/2 <= $step ) { $step= 1; PermuteList( \@list ); $offset= $start= int rand @list; } if( 1 == Lcd( $step, 0+@list ) ) { my @sample; do { return @sample if $size == @sample; push @sample, $list[$offset]; $offset= ( $offset + $step ) % @list; } while( $offset != $start ); } $step++; } }; } my $size= $ARGV[1]; my $iter= GenNextSample( $size, GetPopulation() ); my $samples = 0; while( $samples++ < 64000 ) { my @sample = $iter->(); ProcessSample( @sample ); } #### > perl lcd.pl 16 3 | more Not shuffling ( 100 .. 115 ) ( 112 113 114 ) ( 115 100 101 ) ( 102 103 104 ) ( 105 106 107 ) ( 108 109 110 ) ( 112 115 102 ) ( 105 108 111 ) ( 114 101 104 ) ( 107 110 113 ) ( 100 103 106 ) ( 112 101 106 ) ( 111 100 105 ) ( 110 115 104 ) ( 109 114 103 ) ( 108 113 102 ) ( 112 103 110 ) ( 101 108 115 ) ( 106 113 104 ) ( 111 102 109 ) ( 100 107 114 ) Not shuffling ( 100 .. 115 ) ( 102 103 104 ) ...