use strict; use warnings; 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 $numSets = scalar @sets; my @intersection = (); my $currentSet = 0; my @marker = (0, 0, 0, 0, 0); my $currentItem; # helper functions sub stepMarker { $marker[$currentSet]++; if ($marker[$currentSet] >= scalar @{$sets[$currentSet]}) { # we are at the end of the current set # => abort, there cannot be any more common items last MAIN; } } sub nextSet { $currentSet++; $currentSet %= $numSets; } sub getCurrentItem { return $sets[$currentSet]->[$marker[$currentSet]]; } # main intersection algorithm my $activeItem = getCurrentItem; my $isPresent = 1; MAIN: while (1) { stepMarker(); nextSet; while (($currentItem = getCurrentItem()) < $activeItem) { stepMarker(); } if ($currentItem > $activeItem) { $activeItem = $currentItem; $isPresent = 1; } else { $isPresent++; if ($isPresent == $numSets) { # item has been found present in all sets push @intersection, $activeItem; stepMarker(); $activeItem = getCurrentItem; $isPresent = 1; } } } print "Common items in the $numSets sets: @intersection\n";