Re: Arbitrarily Many Nested Loops



David Formosa (aka ? the Platypus) wrote:
On 29 Mar 2006 16:51:14 -0800, Jacob JKW <jacobcdf@xxxxxxxxx> wrote:
This is what I have:

-------------
#!perl

for (my $i = 0; $i<=$n_ra->[0]; $i++) {
for (my $j = 0; $j<=$n_ra->[1]; $j++) {
for (my $k = 0; $k<=$n_ra->[2]; $k++) {
$prob_ra->[$i+$j+$k] += (
$f_raa->[0]->[$i] *
$f_raa->[1]->[$j] *
$f_raa->[2]->[$k] *
);
}
}
-------------
But that's obviously messy and more imprtantly I'd like to be able to
decide at run time to have how nested levels to go (probably be on the
order of 50 or 60). I assume that there's a canonical manner in which
this should be handled (using closures I'd guess) but I can't
sufficiently summarize my issue to make it Google-able.

I quickly worked out one way to do this, no guarties as to effeceny.

sub closefor (&$@) {
my $sub = shift;
my $range = shift;

return sub {
for my $i (0..$range){
$sub->($i,@_)
}
}
}

sub mulitloop (&@) {
my $sub = shift;
for (@_) {
my $oldsub = $sub;
$sub = closefor {$oldsub->(@_)} $_;
}
$sub->();
}

Your code becomes

mulitloop { my $i = shift;
my $j = shift;
my $k = shift;
$prob_ra->[$i+$j+$k] += $f_raa->[0]->[$i] *
$f_raa->[1]->[$j] *
$f_raa->[2]->[$k]
} @$n_ra;

To convert the algorithm into something that does arbitrarily depth
involves a small reworking the insides so that it works with an
arbitrary number of arguments.

mulitloop {
my $sum = 0;
my $product = 1;
for (my $i; $i<=@#_; $i++) {
$sum += $_[$i];
$product *= $f_raa->[$i]->[$_[$i]];
}
$prob_ra->[$sum] += $product;
} @$n_ra;

I made a few synactical changes but it worked out beautifully. Thank
you very, very much for that. :-)
(Thanks to Jim Gibson and John Krahn who both answered my post as well,
for no particularly good reason I didn't get a chance to try out either
of their code samples.)


--
Please excuse my spelling as I suffer from agraphia. See
http://dformosa.zeta.org.au/~dformosa/Spelling.html to find out more.
Do you think if I became agraphic I could become as good a programmer
as you?

.



Relevant Pages

  • sitemap generator for Perl
    ... I want to run the sitemap generator ... Returns the minimum number of links to traverse from the root URL of ... my $class = shift; ...
    (perl.beginners)
  • Re: Arbitrarily Many Nested Loops
    ... sub closefor { ... my $range = shift; ... sub mulitloop { ... significantly than my original ugly cut-and-paste style, ...
    (comp.lang.perl.misc)
  • Re: How can I create instantiable objects (not classes)?
    ... a child object inherits not only its parent object's ... sub fee { ... my $class = shift; ... For example, an object of type Car might receive a message named "ticket," and since a car does not know what to do with a ticket, it would pass that message to an object of type Driver. ...
    (comp.lang.perl.misc)
  • Re: Packages and returning errors
    ... > array intact. ... sub is_a_instance_method { ... my $class = shift; ... You need to fix the scope of $error by moving its declaration outside ...
    (comp.lang.perl.misc)
  • Re: passing database data to a sub
    ... > I'm not sure of the difference, why isn't it a subroutine? ... > sure about this 'shift' thing anyway :-) ... > sub teardown ... > # Setup the template to use for the output. ...
    (perl.beginners)