Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi perl monks, I'm a complete novice in need of help please. I have a set of elements i.e. {A B C} and need to produce all combinations of this set with a length of 2, i.e. AA AB AC BA BB BC CA CB CC This is not quite permutations or combinations because a single element can occur more than once in a string i.e. AA. Any help would be appreciated. Thanks

Replies are listed 'Best First'.
Re: Combinations of a set of elements
by sauoq (Abbot) on Nov 13, 2002 at 20:44 UTC
Re: Combinations of a set of elements
by VSarkiss (Monsignor) on Nov 13, 2002 at 20:41 UTC

    This is in the perlfaq documents. Try

    perldoc -q permute
    and you can see sample code.

Re: Combinations of a set of elements
by particle (Vicar) on Nov 13, 2002 at 20:56 UTC

    for a different twist, try merlyn's range-based magical autoincrement.

    #!/usr/bin/perl use strict; use warnings; $|++; my $alphaGen = sub { scalar glob "{A,B,C}{A,B,C}" }; print $_,$/ while $_ = $alphaGen->();

    i figure if this is homework, you'd never get away with submitting this answer -- but you (and others) might learn this sweet little trick.

    ~Particle *accelerates*

Re: Combinations of a set of elements
by dreadpiratepeter (Priest) on Nov 13, 2002 at 20:41 UTC
    This smacks of homework, but:
    my @set = qw(A B C); my @list; foreach my $one (@set) { foreach my $two (@set) { push @list,"${one}$two"; } }


    -pete
    "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."
      This is called a cartesian product incidentally.
      This will have a problem, if the set is ("a", "a", "a", "a", "b"), then you will repeat combinations unnecessarily.

        Sets, by definition, don't have duplicate elements.

        Collections which permit duplicate elements are known as "bags" or "multisets."

        -sauoq
        "My two cents aren't worth a dime.";
        
        Maybe not. It depends on whether the duplicates are significant or not. That wasn't specified in the question.

        -pete
        "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."
Re: Combinations of a set of elements
by pg (Canon) on Nov 13, 2002 at 20:57 UTC
    One solution:
    use strict; my @chars = ("a", "a", "b", "c"); my %non_repeat; foreach (@chars) { if (exists($non_repeat{$_})) { $non_repeat{$_} = 2; } else { $non_repeat{$_} = 1; } } my @combinations; my ($first, $second); my @keys = keys %non_repeat; my ($index1, $index2); for ($index1 = 0; $index1 <= $#keys; $index1 ++) { if ($non_repeat{$keys[$index1]} == 2) { push @combinations, $keys[$index1] x 2; } for ($index2 = $index1 + 1; $index2 <= $#keys; $index2 ++) { push @combinations, $keys[$index1] . $keys[$index2]; push @combinations, $keys[$index2] . $keys[$index1]; } } print join(",", @combinations);
Re: Combinations of a set of elements
by Enlil (Parson) on Nov 13, 2002 at 20:44 UTC
    Hrm.. sounds a bit like homework, but I will give you a start. (If I am wrong and not homework, I apologize), but anyhow the first thing that comes to mind is:
    my @initial_array = ("A","B","C");
    and a couple foreach loops. Though TMTOWTDI is sure to come into play.

    Good Luck

    enlil

Re: Combinations of a set of elements
by Ananda (Pilgrim) on Nov 14, 2002 at 06:04 UTC

    This may help you. The code below generates a array list that eliminates redundant data.

    my @set = qw(A B C D A);

    my @list;

    my $elm;

    my $count=0;

    foreach my $one (@set) {

    foreach my $two (@set) {

    $elm ="$one"."$two";

    foreach $list(@list){$count++ if ($list eq elm);}

    push @list,"$one$two" if($count eq 0);

    }

    }

    Cheers!!!!

    Anandatirtha

      Correction

      foreach $list(@list){$count++ if ($list eq $elm);}

      Anandatirtha