Cartesian product of two or more lists: Difference between revisions

Content added Content deleted
(→‎{{header|F Sharp|F#}}: Claim the extra credit)
(Added Perl example)
Line 1,616: Line 1,616:
val product'' : 'a list tuple -> 'a tuple list = <fun>
val product'' : 'a list tuple -> 'a tuple list = <fun>
</lang>
</lang>

=={{header|Perl}}==
==== Iterative ====
Nested loops, with a short-circuit to quit early if any term is an empty set.
<lang perl>sub cartesian {
my $sets = shift @_;
for (@$sets) { return [] unless @$_ }

my $products = [[]];
for my $set (reverse @$sets) {
my $partial = $products;
$products = [];
for my $item (@$set) {
for my $product (@$partial) {
push @$products, [$item, @$product];
}
}
}
$products;
}

sub product {
my($s,$fmt) = @_;
my $tuples;
for $a ( @{ cartesian( \@$s ) } ) { $tuples .= sprintf "($fmt) ", @$a; }
$tuples . "\n";
}

print
product([[1, 2], [3, 4] ], '%1d %1d' ).
product([[3, 4], [1, 2] ], '%1d %1d' ).
product([[1, 2], [] ], '%1d %1d' ).
product([[], [1, 2] ], '%1d %1d' ).
product([[1,2,3], [30], [500,100] ], '%1d %1d %3d' ).
product([[1,2,3], [], [500,100] ], '%1d %1d %3d' ).
product([[1776,1789], [7,12], [4,14,23], [0,1]], '%4d %2d %2d %1d')</lang>
{{out}}
<pre>(1 3) (1 4) (2 3) (2 4)
(3 1) (3 2) (4 1) (4 2)


(1 30 500) (1 30 100) (2 30 500) (2 30 100) (3 30 500) (3 30 100)

(1776 7 4 0) (1776 7 4 1) (1776 7 14 0) (1776 7 14 1) (1776 7 23 0) (1776 7 23 1) (1776 12 4 0) (1776 12 4 1) (1776 12 14 0) (1776 12 14 1) (1776 12 23 0) (1776 12 23 1) (1789 7 4 0) (1789 7 4 1) (1789 7 14 0) (1789 7 14 1) (1789 7 23 0) (1789 7 23 1) (1789 12 4 0) (1789 12 4 1) (1789 12 14 0) (1789 12 14 1) (1789 12 23 0) (1789 12 23 1)</pre>

==== Glob ====
This being Perl, there's more than one way to do it. A quick demonstration of how <code>glob</code>, more typically used for filename wildcard expansion, can solve the task.
<lang perl>$tuples = [ map { [split /:/] } glob '{1,2,3}:{30}:{500,100}' ];

for $a (@$tuples) { printf "(%1d %2d %3d) ", @$a; }</lang>
{{out}}
<pre>(1 30 500) (1 30 100) (2 30 500) (2 30 100) (3 30 500) (3 30 100)</pre>


=={{header|Perl 6}}==
=={{header|Perl 6}}==