R
Rainer Weikusat
For some rather weird problem, I needed a way to generate an ordered
list of all pairs which can be formed from the sequence 0, 1, 2, ... 31.
I figured that it should be possible to write a recursive function
taking a 'ring size' (32 in this case) and a 'depth' (2) argument which
would return a generator cycling through all pairs, with the
function generating the generator being capable of returning a working
result for any combination of size and depth. This turned out to be
amazingly more complicated than I originally thought. The result I came
up with is
---------
sub ring
{
my $size = $_[0];
my $cur;
$cur = -1;
return sub {
return $cur = ($cur + 1) % $size;
}
}
sub rings
{
my ($size, $depth) = @_;
my ($cur, $ring_next, $tail, $last_t0);
$ring_next = ring($size);
return $ring_next if $depth == 1;
$last_t0 = $cur = -1;
$tail = rings($size, $depth - 1);
return sub {
my @tail;
@tail = $tail->();
$cur = $ring_next->() if !$tail[0] && $last_t0;
$last_t0 = $tail[0];
return ($cur, @tail);
};
}
my $r = rings(32, 2);
print(join(',', $r->()), "\n") for 0 .. 1023;
list of all pairs which can be formed from the sequence 0, 1, 2, ... 31.
I figured that it should be possible to write a recursive function
taking a 'ring size' (32 in this case) and a 'depth' (2) argument which
would return a generator cycling through all pairs, with the
function generating the generator being capable of returning a working
result for any combination of size and depth. This turned out to be
amazingly more complicated than I originally thought. The result I came
up with is
---------
sub ring
{
my $size = $_[0];
my $cur;
$cur = -1;
return sub {
return $cur = ($cur + 1) % $size;
}
}
sub rings
{
my ($size, $depth) = @_;
my ($cur, $ring_next, $tail, $last_t0);
$ring_next = ring($size);
return $ring_next if $depth == 1;
$last_t0 = $cur = -1;
$tail = rings($size, $depth - 1);
return sub {
my @tail;
@tail = $tail->();
$cur = $ring_next->() if !$tail[0] && $last_t0;
$last_t0 = $tail[0];
return ($cur, @tail);
};
}
my $r = rings(32, 2);
print(join(',', $r->()), "\n") for 0 .. 1023;