#!/usr/bin/perl -w

sub intersection {
    my ( $i, $sizei ) = ( 0, scalar keys %{ $_[0] } );
    my ( $j, $sizej );

    # Find the smallest hash to start.
    for ( $j = 1; $j < @_; $j++ ) {
        $sizej = scalar keys %{ $_[ $j ] };
        ( $i, $sizei ) = ( $j, $sizej )
            if $sizej < $sizei;
    }

    my ( $possible, %intersection );

 TRYELEM:
    # Check each possible member against all the remaining sets.
    foreach $possible ( keys %{ splice @_, $i, 1 } ) {
        foreach ( @_ ) {
            next TRYELEM unless exists $_->{ $possible };
        }
        $intersection{$possible} = undef;
    }

    return \%intersection;
}

@Cats{    qw(cat lion tiger)  } = ( );
@Asian{   qw(tiger panda yak) } = ( );
@Striped{ qw(zebra tiger)     } = ( );

$Cats_Asian_Striped = intersection( \%Cats, \%Asian, \%Striped );

print join(" ", keys %{ $Cats_Asian_Striped }), "\n";
