#!/usr/bin/env perl use strict; use warnings; my %data = ( A => [qw{ant bee cat dog eel fly gnu hog}], B => [qw{ant cat eel gnu}], C => [qw{bee dog fly hog}], D => [qw{cat fly ant}], E => [qw{ant dog gnu}], F => [qw{gnu bee}], G => [qw{eel hog}], H => [qw{zoo}], I => [qw{}], ); my (%venn, %temp); for my $set (sort keys %data) { my @elems = @{$data{$set}}; @elems = ('') unless @elems; for my $elem (@elems) { push @{$temp{$elem}}, $set; } } for my $elem (keys %temp) { my @sets = @{$temp{$elem}}; for my $i (0 .. $#sets) { my @subsets = @sets[$i .. $#sets]; my $key = shift @subsets; push @{$venn{$key}}, $elem; for my $set (@subsets) { $key .= "-$set"; push @{$venn{$key}}, $elem; } } } my $fmt = "%-7s %s %s\n"; { no warnings 'qw'; printf $fmt, qw{Sets # Elements}; printf $fmt, qw{---- - --------}; } for my $sets (sort keys %venn) { printf $fmt, $sets, 0+@{$venn{$sets}}, join ' ', sort @{$venn{$sets}}; }