in reply to Re^4: Derangements iterator (callbacks)
in thread Derangements iterator
Not even understanding jdporter's algorithm, I converted it to be iterative (or perhaps more precisely, lazily evaluated). I made the derange function print only the first 15 results, for convenient testing of large inputs.
sub _derange_iter { my ($cb, $todo, @v) = @_; @$todo or return do { $cb->( @v ); sub {} }; # this line was wrong b +efore my %seen; @seen{@v} = (); my ( $range, @todo ) = @$todo; my @sub_iter = map { my $my_ = $_; sub { _derange_iter ( $cb, \@todo, @v, $my_ ) } } grep { ! exists $seen{$_} } @$range; return sub {} unless (@sub_iter); # Grab and unwrap an iterator from the list my $iter = (shift @sub_iter)->(); return sub { my $rval; $iter = (shift @sub_iter)->() until ($rval = $iter->() or @sub_iter == 0); return $rval; } } sub derange(&@) { my $cb = shift; my $iter = _derange_iter( $cb, [ map { my $x = $_; [ grep { $_ ne $x } @_ ] } @_ ] ); for (1..15) { $iter->(); } } derange { print "@_\n" } @ARGV;
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^6: Derangements iterator (callbacks)
by tye (Sage) on Dec 30, 2005 at 19:11 UTC | |
by Roy Johnson (Monsignor) on Jan 01, 2006 at 15:21 UTC |