#!/usr/bin/perl -w
# -T can only be given on the command line (taint checking)
use strict; # homework by Eric Auer...

# helper functions to modify sets of results (to be
# precise: the data are hashrefs, the keys are the files
# and the values are the weights)

# WARNING: the first arg is not only returned (a ref to it)
# but also modified in place as a side effect. This is why
# we have setCOPY.


sub setCOPY { # make an unlinked copy of a simple hash
  my %newset = ();
  my %oldset = %{$_[0]};
  foreach my $thekey (keys %oldset) {
    $newset{$thekey} = $oldset{$thekey}; # copy it...
  }
  return \%newset;
}


sub setOR { # union of two sets, maximum of weights
  my %newset = ();
  my %set2;
  %newset = %{$_[0]};
  %set2 = %{$_[1]};
  foreach my $thekey (keys %set2) {
    if (defined $newset{$thekey}) {
      # combine the weights somehow: use MAXIMUM
      my $val1 = $newset{$thekey};
      my $val2 = $set2{$thekey};
      $newset{$thekey} = ($val2 > $val1) ? $val2 : $val1;
    } else {
      $newset{$thekey} = $set2{$thekey}; # simple copy
    }
  }
  return \%newset;
}


sub setAND { # "product" (?)  of two sets, minimum of weights
  my %newset = ();
  my %set2;
  %newset = %{$_[0]};
  %set2 = %{$_[1]};
  foreach my $thekey (keys %set2) {
    if (defined $newset{$thekey}) {
      # combine the weights somehow: use MINIMUM
      my $val1 = $newset{$thekey};
      my $val2 = $set2{$thekey};
      $newset{$thekey} = ($val2 > $val1) ? $val2 : $val1;
    } else {
      delete $newset{$thekey}; # remove if not in BOTH
    }
  }
  foreach my $thekey (keys %newset) {
    if (!defined $set2{$thekey}) {
      delete $newset{$thekey}; # remove if not in BOTH
    }
  }
  return \%newset;
}


sub setSUB { # remove whatever is in set2 from set1
  my %newset = ();
  my %set2;
  %newset = %{$_[0]};
  %set2 = %{$_[1]};
  foreach my $thekey (keys %set2) {
    if (defined $newset{$thekey}) {
      delete $newset{$thekey}; # remove if any...
    }
  }
  return \%newset;
}


return 1; # make require succeed

