In Perl, how can I output the diagonal of the Cartesian product of a set with itself before all the off-diagonal elements?

StackOverflow https://stackoverflow.com/questions/23656820

  •  22-07-2023
  •  | 
  •  

Question

I want to output all the combinations of two letters, but I want the combinations between the same letters to be shown first. Basically, I want to get something like this:

If I have

@list = ("A", "B", "C")

I want my output to be:

AA  -
BB  -
CC  -
AB
AC
BA
BC
CA
CB

Normally, if I'd just use two for loops I'd get

AA  -
AB
AC
BA
BB  -
BC
CA
CB
CC  -

Is there any fast (easy to understand / simple) way to get the output as I want?

Was it helpful?

Solution 4

for my $e (@list) {
    say $e.$e;
}

for my $i (0..$#list) {
    for my $j (0..$#list) {
        say $list[$i].$list[$j] if $i != $j;
    }
}

It should meet your requirements as it's 3 times faster than previously presented solutions[1], yet it's still quite clear.


  1. There was a benchmark in another answer, but it got deleted.

OTHER TIPS

This has already been addressed, but I think the simplest solution is just to handle your special case in custom code and then rely on the standard modules for everything else.

For combinatoric modules, can use either Algorithm::Combinatorics or Math::Combinatorics.

use strict;
use warnings;

use Algorithm::Combinatorics qw(variations_with_repetition);
use List::MoreUtils qw(uniq);

my @set = ('A'..'C');
my $length = 3;

# Trivial Diagonal Solutions
for my $element (@set) {
    my @solution = ($element) x $length;
    print "@solution\n"
}

# All Other Solutions
my $iter = variations_with_repetition(\@set, $length);
while (my $p = $iter->next) {
    next if 1 == uniq @$p;
    print "@$p\n"
}

I can't think of an easier way than:

@letters = ( 'A', 'B' );
@list = ( $letters[0].$letters[0], $letters[1].$letters[1], $letters[0].$letters[1], $letters[1].$letters[0] );
for (glob("{A,B,C}{A,B,C}")) {
  print;
  print " -" if /(.)\1/;
  print "\n";
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top