use Data::Dumper; my @sets = ([ 0, 1, 2, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, ], [ 0, 3, 7, 8, 10, 11, 13, 14, 16, ], [ 0, 1, 2, 3, 5, 7, 8, 10, 11, 12, 13, 14, 16, ], [ 2, 3, 4, 6, 7, 8, 10, 11, 12, 14, 16, ], [ 0, 1, 2, 3, 7, 8, 9, 10, 11, 13, 14, 15, ]); my @common = (); ### helpers sub max_element { my $max = -1; for (@sets) { $max = $_->[0] if $_->[0] > $max; } return $max; } sub all_the_same { my $element; for (@sets) { if (not defined $element) { $element = $_->[0]; } else { return 0 if $element != $_->[0]; } } return 1; } ### main loop my $done = 0; while (not $done) { foreach (@sets) { $done++ if @$_ == 0; } if (all_the_same()) { push @common, $sets[0][0]; shift @$_ for @sets; } else { my $max = max_element(); for (@sets) { shift @$_ if $_->[0] < $max; } } ## uncomment these to see how it works step by step: # print Dumper(\@sets, \@common), "\n"; # } print "@common\n";