It was easy once I figured out that it's just like counting... hope to have time this weekend to make it more feature-ful and put it on CPAN!
#!/usr/bin/env perl use strict; use warnings; use Data::Dump; sub single_change_iterator { my @domains = @_; my $it = 0; my @dir = (1) x @domains; my @pos = (0) x @domains; $it = sub { # Initializion. Next call, use the real iterator. $it = sub { my $cur_dom; for ($cur_dom = 0; $cur_dom < @domains or return; # No more changes! ++$cur_dom) { # Are we at end position of this domain? my $upward = $dir[$cur_dom]==1; if ($pos[$cur_dom] == ($upward ? $#{$domains[$cur_dom] +} : 0)) { # flip domain's direction, let loop continue $dir[$cur_dom] *= -1; } else { # Move current domain to next position $pos[$cur_dom] += $dir[$cur_dom]; last; } } return [$cur_dom, $domains[$cur_dom][$pos[$cur_dom]]]; }; # End first call by initializing all domains return map [$_, $domains[$_][0]], 0 .. $#domains }; return \$it; } my $combo_it = single_change_iterator(['X','Y'], [qw(a b c)], [44,55]) +; my @changes; dd @changes while @changes = &$$combo_it; =head1 NAME single_change_itertor - Help build Cartesian product, by changing one +value at a time =head1 SYNOPSIS use Data::Dump; my $it = single_change_itertor(['X','Y'], [qw(a b c)], [1,2]); dd $_ while $_ = &$$it; prints ([0, "X"], [1, "a"], [2, 44]) [0, "Y"] [1, "b"] [0, "X"] [1, "c"] [0, "Y"] [2, 55] [0, "X"] [1, "b"] [0, "Y"] [1, "a"] [0, "X"] =head1 DESCRIPTION This finds a way to cycle through all possible combinations of the given sets- their Cartesian Product- by changing a single element at a time. Given a set of domains, returns a handle to an iterator showing which position changes, and what to. Similar to a Gray code, which cycles through a set of numbers while only changing one digit. Each call returns a list of array references. The inner array reference is a pair, [ index of domain that has a change , new value ] The first iteration returns a pair for each domain so as to initialize all the domains. Each subsequent call returns a single pair.

In reply to Re^2: Minimally changing combinations by Yary
in thread Minimally changing combinations by Yary

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.