-
Notifications
You must be signed in to change notification settings - Fork 37
/
oo.pl
48 lines (41 loc) · 1.36 KB
/
oo.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
use v6;
##########################
# OO solution by eric256 #
##########################
my @loops = ([1..3], ['a'..'e'], ['foo', 'bar']);
class MultiCounter {
has @.positions is rw;
has @.lengths is rw;
submethod BUILD() { @.positions = (0) xx (@.lengths.end + 1); }
method inc () returns Bool {
@.positions[*-1]++;
for reverse (0..@.lengths.end - 1) -> $i {
if (@.positions[$i + 1] > @.lengths[$i + 1]) {
@.positions[$i]++;
@.positions[$i + 1] = 0;
}
}
return (@.positions[0] > @.lengths[0]) ?? 0 !! 1;
}
}
class NestedLoops {
has @.loops is rw;
has MultiCounter $.counter is r;
submethod BUILD($self:) {
$self.reset;
}
method reset () {
$.counter = MultiCounter.new( :lengths( @.loops.map: {.end } ) );
}
multi method iter () returns Bool { $.counter.inc; }
multi method iter ($self: Code $code) {
while ($self.iter) { $code($self.data) };
$self.reset;
}
method data () {
return map -> $i { @.loops[$i][ $.counter.positions[$i] ] }, 0 .. @.loops.end;
};
}
my $counter = NestedLoops.new( :loops(@loops) );
$counter.iter( sub { say "CODE BLOCK " ~ @_ } );
while ($counter.iter) { say "WHILE LOOP " ~ $counter.data.join(" "); }