RosettaCodeData/Task/Set-consolidation/Perl/set-consolidation.pl
2016-12-05 22:15:40 +01:00

47 lines
1.2 KiB
Perl

use strict;
use English;
use Smart::Comments;
my @ex1 = consolidate( (['A', 'B'], ['C', 'D']) );
### Example 1: @ex1
my @ex2 = consolidate( (['A', 'B'], ['B', 'D']) );
### Example 2: @ex2
my @ex3 = consolidate( (['A', 'B'], ['C', 'D'], ['D', 'B']) );
### Example 3: @ex3
my @ex4 = consolidate( (['H', 'I', 'K'], ['A', 'B'], ['C', 'D'], ['D', 'B'], ['F', 'G', 'H']) );
### Example 4: @ex4
exit 0;
sub consolidate {
scalar(@ARG) >= 2 or return @ARG;
my @result = ( shift(@ARG) );
my @recursion = consolidate(@ARG);
foreach my $r (@recursion) {
if (set_intersection($result[0], $r)) {
$result[0] = [ set_union($result[0], $r) ];
}
else {
push @result, $r;
}
}
return @result;
}
sub set_union {
my ($a, $b) = @ARG;
my %union;
foreach my $a_elt (@{$a}) { $union{$a_elt}++; }
foreach my $b_elt (@{$b}) { $union{$b_elt}++; }
return keys(%union);
}
sub set_intersection {
my ($a, $b) = @ARG;
my %a_hash;
foreach my $a_elt (@{$a}) { $a_hash{$a_elt}++; }
my @result;
foreach my $b_elt (@{$b}) {
push(@result, $b_elt) if exists($a_hash{$b_elt});
}
return @result;
}