[Wellington-pm] Combinatorics

Simon Green mail at simon.green
Tue Jul 4 03:00:18 PDT 2017



On 04/07/17 21:45, Peter Kelly wrote:
> So, let me start with a confession - I stopped at sixth form maths.  
> 
> The programme I am trying to write this evening seeks to combine one
> element of set A, with one element of set B, one element of set C, etc.
> 
> I don't know beforehand how many sets there will be.   Each set has a
> different number of members.
> 
> I need to test all the combinations, so that if we have sets A B C, and
> A has 2 items, B has 5 items, and C has 2 items, we end up with 2*5*2
> combinations = 20.
> 
> k possible combinations of items in a single set is conveniently
> available through Algorithm::Combinatorics.  I've used that elsewhere in
> this programme but it doesn't seem to handle multiple sets.
> 
> I've spent the last few hours on this, and have started a few ways.  I
> have something written using recursion, tracking which sets have already
> been accessed using an arrayref, and passing around a hashref.  But I am
> seriously bogged down in that "delete the code and start again" sort of way.
> 
> Are there any better ideas that any of you can point me to?

Something like the below. I'm sure there is a more eloquent way to write
it, but it does the job and sometimes that's good enough™

-- 
Simon

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use 5.10.1;

my @sets = ( [2,3,4], [3,4,5], [6,7,8], [10,12,13]);
my @results = ();


sub _combinate {
    my ($result, $group, $set, @sets) = @_;
    foreach my $item (@$set) {
        if (scalar(@sets)) {
        _combinate($result, [@$group, $item], @sets);
        }
        else {
            push @$result, [ @$group, $item ];
        }
    }
}

_combinate(\@results, [], @sets);
say Dumper(\@results);


More information about the Wellington-pm mailing list