-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathcartesian_product_iter.pl
executable file
·57 lines (43 loc) · 1.03 KB
/
cartesian_product_iter.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/perl
# Daniel "Trizen" Șuteu
# Date: 23 April 2017
# https://github.com/trizen
# Iterative algorithm for computing the Cartesian product.
# Algorithm from:
# https://stackoverflow.com/a/10947389
use 5.016;
use warnings;
sub cartesian(&@) {
my ($callback, @arrs) = @_;
my ($more, @lengths);
foreach my $arr (@arrs) {
my $end = $#{$arr};
if ($end >= 0) {
$more ||= 1;
}
else {
$more = 0;
last;
}
push @lengths, $end;
}
my @temp;
my @indices = (0) x @arrs;
while ($more) {
@temp = @indices;
for (my $i = $#indices ; $i >= 0 ; --$i) {
if ($indices[$i] == $lengths[$i]) {
$indices[$i] = 0;
$more = 0 if $i == 0;
}
else {
++$indices[$i];
last;
}
}
$callback->(map { $_->[CORE::shift(@temp)] } @arrs);
}
}
cartesian {
say "@_";
} (['a', 'b'], ['c', 'd', 'e'], ['f', 'g']);