in reply to Re^3: Cartesian Cross-Products
in thread Cartesian Cross-Products

Hi, Perl n00b here. Check out my recursive solution for any number of sets. Feel the scheme.
sub cartesian { my @sets = @_; # base case if (@sets == 0) { return ([]); } my @first = @{@sets[0]}; # recursive call shift @sets; my @rest = cartesian(@sets); my @result = (); foreach my $element (@first) { foreach my $product (@rest) { my @newSet = @{$product}; unshift (@newSet, $element); push (@result, \@newSet); } } return @result; }

Replies are listed 'Best First'.
Re^5: Cartesian Cross-Products
by psini (Deacon) on Aug 09, 2010 at 17:54 UTC

    Update: Sorry, deleted rerroneous post

    Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."

Re^5: Cartesian Cross-Products
by drt (Initiate) on Feb 15, 2012 at 21:54 UTC

    I had the same thought also (to use a recursive algorithm), but your code didn't seem complete or it didn't work the way I expected. There are certainly more Perlish ways to code this with map etc., but it works. Cartesian product of multiple lists using recursion.

    use Data::Dumper; my $letters = [qw(a b c)]; my $numbers = [1..3]; my $words = [qw(you me)]; my $result = cartesian($letters, $numbers, $words); print Dumper( $result ); sub cartesian { my ($set, @sets) = @_; my @expanded; # base case if ( !@sets ) { foreach ( @{$set} ){ push @expanded, [$_]; } } # recursive call else { my @product = @{ cartesian(@sets) }; foreach my $element ( @{$set} ) { foreach my $product ( @product ) { push @expanded, [ $element, @{$product} ]; } } } return \@expanded; }