Using this technique, the task of creating an iterator boils down to creating a glob string.
# This one constructs a simple glob and returns the sub that will # iterate through it. sub iter_powerset { my @elems = @_; my $glob_str = join 'X', map {"{$_,}"} 0..$#elems; sub { @elems[grep length, split 'X', scalar glob $glob_str] }; } # This is an auxiliary to iter_powerset2 (below). The glob expression +is # more complex, in order to get the desired order of output. As the nu +mber # of elements grows, the glob string balloons, quickly becoming too la +rge # to work. sub powerset_glob { my ($car, @cdr) = @_; if (@cdr) { my $cdr_globstr = powerset_glob(@cdr); return (join ',', "{$car", "$car+$cdr_globstr", "$cdr_globstr}"); } else { return $car } } # Call the glob string builder and return the iterator subroutine sub iter_powerset2 { my @elems = @_; my $glob_str = powerset_glob(0..$#elems); sub { @elems[grep length, split /\+/, scalar glob $glob_str] }; } # Demonstration code. Call either iter_powerset function my $iter = iter_powerset2(2,3,5,7); while (my @set = $iter->()) { print "<@set>\n"; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Glob powerset with progressive ordering
by tlm (Prior) on Apr 27, 2005 at 07:10 UTC | |
by Roy Johnson (Monsignor) on Apr 27, 2005 at 10:53 UTC |