#! perl -sw use strict; sub roundRobin { my @q; my $next = -1; my %self = ( values => sub { return @q[@_]; }, size => sub { return scalar @q; }, pos => sub { return 0+$next; }, add => sub { return push @q, @_; }, del => sub { my ($i, %del) = (0); @del{@_} = undef; @q = grep { exists $del{$_} ? ($next -= $i <= $next) && 0 : ++$i } @q; return 1; }, next => sub { return undef if not @q; ++$next; $next %= @q; return $q[$next]; }, shuffle => sub { my $t; $t = $_ + rand @q - $_ and @q[$_, $t] = @q[$t, $_] for (0..$#q); }, ); return %self; } my %rr = roundRobin(); $rr{add}( 'a' .. 'z' ); print $rr{size}(), $rr{values}(0..$rr{size}()-1), $/; $rr{add}( 'k' .. 'q' ); print $rr{size}(), $rr{values}(0..$rr{size}()-1), $/; $rr{shuffle}(); while ( my $item = $rr{next}() ) { my $pos = $rr{pos}(); print " @{[$rr{values}( 0 .. $pos -1 )]}". "<@{[$rr{values}($pos)]}>". "@{[$rr{values}($pos+1..$rr{size}()-1 )]}"; if (rand(8) < 1) { my $new = chr(95+rand 26); $rr{add}( $new ); print "\t --added ", $new; } if (rand(8) < 1) { my $toDelete = $item; $toDelete = do { $rr{values}( rand( $rr{size}()) ) } until $toDelete ne $item; print "\t--deleting: '", $toDelete; $rr{del}( $toDelete ); } print $/; select undef, undef, undef, .5; }