http://www.perlmonks.org?node_id=1053907

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

Hi PerlMonks,

I have an array like @array = qw/a b c d/; I am interested to find out the pairwise difference and product between any two elements in the array by taking out each element from the array and then calculating the difference and the product as shown in the expected result. Since there are 4 elements, there will be n(n-1)/2=6 pairwise differences and products, where n=4.

#!usr/bin/perl use warnings; @array=qw/a b c d/; # Code for taking out each element: foreach $item (@array) { $each_ele=$item; print"\n Each element: $each_ele\n"; } # Code ????? ............ ............ exit;

The expected result should look like:

Difference: a-b a-c a-d b-c b-d c-d Product: a.b a.c a.d b.c b.d c.d
  • Comment on How can one find out the pairwise difference and product between elements in a perl array without using a perl module?
  • Select or Download Code

Replies are listed 'Best First'.
Re: How can one find out the pairwise difference and product between elements in a perl array without using a perl module?
by Corion (Patriarch) on Sep 13, 2013 at 12:25 UTC

    I suggest you look at the code of a module implementing this, and then take that code.

Re: How can one find out the pairwise difference and product between elements in a perl array without using a perl module?
by hdb (Monsignor) on Sep 13, 2013 at 12:33 UTC

    For starters, here is a destructive solution for the differences:

    use strict; use warnings; my @array=qw/a b c d/; while( my $first = shift @array ) { print "$first-$_\n" for @array; }
Re: How can one find out the pairwise difference and product between elements in a perl array without using a perl module?
by LanX (Saint) on Sep 13, 2013 at 12:56 UTC
    ... and the obvious non-destructive solution is to use to nested loops operating on indices.

    So whats the problem?

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: How can one find out the pairwise difference and product between elements in a perl array without using a perl module?
by hdb (Monsignor) on Sep 13, 2013 at 13:50 UTC

    And a complete solution:

    use strict; use warnings; my @array=qw/a b c d/; my $diff = join"",map{s/(\d+)/$array[$1]/g;$_.$/}grep{eval$_<0}glob("{ +".join(",",0..$#array)."}-{".join(",",0..$#array)."}"); my $prod = $diff; $prod =~ tr/-/./; print "Differences:\n$diff\nProducts:\n$prod";
Re: How can one find out the pairwise difference and product between elements in a perl array without using a perl module?
by Arunbear (Prior) on Sep 13, 2013 at 13:26 UTC
    One way (differences and products are left as an exercise):
    % perl -E '@a = 1 .. 4; for my $x (@a) { %set = map { $_ => 1 } @a; de +lete $set{$x}; say "$x, $_" for keys %set; }' 1, 4 1, 3 1, 2 2, 4 2, 1 2, 3 3, 4 3, 1 3, 2 4, 1 4, 3 4, 2 %
Re: How can one find out the pairwise difference and product between elements in a perl array without using a perl module?
by Laurent_R (Canon) on Sep 13, 2013 at 15:55 UTC

    Not sure it helps a lot in your case, but this is one possible way to generate permutations in this session under the Perl debugger:

    DB<1> @array=qw/a b c d/ DB<2> $stringified = join ',', @array; DB<3> @permutations = glob "{$stringified}" x 2; DB<4> map {s/(.)(.)/$1-$2/} @permutations DB<5> x @permutations 0 'a-a' 1 'a-b' 2 'a-c' 3 'a-d' 4 'b-a' 5 'b-b' 6 'b-c' 7 'b-d' 8 'c-a' 9 'c-b' 10 'c-c' 11 'c-d' 12 'd-a' 13 'd-b' 14 'd-c' 15 'd-d'

    Of course, in your case, additional filtering would be necessary. I think that the modules mentionned by other monks are probably a better solution.

Re: How can one find out the pairwise difference and product between elements in a perl array without using a perl module?
by Anonymous Monk on Sep 14, 2013 at 01:58 UTC

    Not as fancy as some, but gives the output you specified. O might not be too bad as it's only a single pass through for the main number, and both operations can be done on the same pass. As always, YMMV.

    #!/usr/bin/perl use strict; use warnings; my @array=qw/a b c d/; while ( @array > 1 ) { my $first = shift(@array); for my $next ( @array ) { # take diff $first - $next; # take product $first * $next; print sprintf("%-8s%s\n","$first - $next","$first * $next"); } } exit; __END__ a - b a * b a - c a * c a - d a * d b - c b * c b - d b * d c - d c * d