eric256,
Sure! First I will give an explanation of how the logic works and then a blow by blow of how the code accomplishes that logic.

Imagine one of those combination locks on a briefcase or a suitcase where there are a series of wheels and you need to get the correct numbers lined up for the lock to open. Each one of the wheels represents a level in our nested for loop with the left most being the outer and the right most being the inner. Unlike real combination locks though, our wheels have different number of values since the arrays may too.

The idea is to start with each wheel on the first setting and incriment the right most wheel (most inner loop) one turn each time. The positions of all the wheels correspond to positions in different arrays. We collect the values, try to open the lock, and continue. When we have tried all the values of the right most wheel, we set it back to the initial position and try the one just to its left. We repeat this process until all combinations have been tried.

The code is a bit trickier because we added in a few options:
# This says that I will be taking 3 named parameters # that can appear in any order, but 1 is required (++) sub NestedLoop (++@loop, +$OnlyWhen, +$code) returns Ref { # We start with all 0s (arrays) except the last wheel # This is so the first turn is in the correct position my @pos = 0 xx (@loop.elems - 1), -1; # We are creating an iterator so we return a code ref return sub { # We need to collect the values of the arrays # Since we are counting in indices my @group; # We added support for $OnlyWhen so each iteration # May actually be an unknown number of turns # So we loop until the condition is satisfied loop { # If in the process of turning the right most # wheel, we exceed the end - we turn a new wheel if ++@pos[-1] > @loop[-1].end { # We start at the nearest wheel to the right # and work to the left looking for 1 that # can be turned without exceeding the end for reverse 0 .. @pos.end - 1 -> $i { next if @pos[$i] == @loop[$i].end; # We turn that wheel and reset all the # wheels to the right to their star pos ++@pos[$i]; @pos = (@pos[0..$i], 0 xx (@pos.end - $i)) and las +t; } } # If we were not able to reset the right most # Wheel we must have not been able to move the # Left most wheel, which means we are done return () if @pos[-1] > @loop[-1].end; # We populate the @group with the actual values # Since we were just keeping track of indices @group = map -> $i { @loop[$i][@pos[$i]] } 0 .. @pos.end; # Since $OnlyWhen is optional, see if it is a # code ref execute it and loop if it doesn't # return a true value if $OnlyWhen.does(Code) { $OnlyWhen(@group) or next } # Execute the optional $code ref if it was defined $code(@group) if $code.does(Code); # End the infinite loop last; } # Return the values for this iteration of the loop return @group; }; };

Cheers - L~R


In reply to Re^3: Perl6 Contest #2: P6 That Doesn't Look Like P5 by Limbic~Region
in thread Perl6 Contest #2: P6 That Doesn't Look Like P5 by Limbic~Region

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.