#!/usr/bin/perl -w

sub difference {
    my %difference;
  
    @difference{ keys %{ shift() } } = ( );

    while ( @_ and keys %difference ) {
        # Delete all the members still in the difference
        # that are also in the next set.
        delete @difference{ keys %{ shift() } };
    }
    
    return \%difference;
}

@Canines     { qw(dog wolf)      } = ( );
@Domesticated{ qw(dog cat horse) } = ( );

$difference = difference(\%Canines, \%Domesticated);
print join(' ', keys %$difference), "\n";

sub symmetric_difference {
    my %symmetric_difference;

    my ( $element, $set );

    while ( defined ( $set = shift( @_ ) ) ) {
        while ( defined ( $element = each %$set ) ) {
            $symmetric_difference{ $element }++;
        }
    }
    delete @symmetric_difference{
        grep( ( $symmetric_difference{ $_ } & 1 ) == 0,
             keys %symmetric_difference)
    };
    return \%symmetric_difference;
}

@Polar{ qw(polar_bear penguin)    } = ();
@Bear{  qw(polar_bear brown_bear) } = ();
@Bird{  qw(penguin condor)        } = ();

$SymmDiff_Polar_Bear_Bird =
    symmetric_difference( \%Polar, \%Bear, \%Bird );

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