#!/usr/bin/perl

use strict;
use warnings;

# enumerateOccurrences
# This script reads files supplied as command-line arguments or on STDIN
# and outputs a report on which out of a set of expected values occurred
# in these input files.
# The "expected values" are supposed to be a sequence of values
# starting with the value specified by the first command-line arg
# and proceeding in "natural" order (e.g. "1", "2", "3", ..."
# or "a", "b", "c", ...)
# The number of expected values is specified by the second command-line arg.
# The files to be read are specified as the remaining command-line args.
# Example of use: enumerateOccurrences "000" 1000 file_with_3_digit_numbers
#
# Cameron Hayne (macdev@hayne.net)  August 2006


my $scriptName = "enumerateOccurrences";
if (scalar(@ARGV) < 2)
{
    die "Usage: $scriptName firstValue numValues [file1 file2 ...]\n";
}

my $firstExpectedValue = shift; # first command-line arg
my $numExpectedValues = shift;  # second command-line arg

# create a hash with all expected values
my %occurrences;
for (my $i = 0, my $value = $firstExpectedValue;
     $i < $numExpectedValues; $i++, $value++)
{
    $occurrences{$value} = 0;
}

# read files supplied as command-line args or STDIN
# and record the occurences of each value in %occurrences
my $numValues = 0;
while (<>)
{
    chomp();
    my $value = $_;
    ++$numValues;

    if (defined($occurrences{$value}))
    {
        ++$occurrences{$value};
    }
    else
    {
        print "Unexpected value: $value\n";
    }
}

sub printReport($$$)
{
    my ($min, $max, $label) = @_;

    my $needLabel = 1;
    foreach my $value (sort keys %occurrences)
    {
        my $numSeen = $occurrences{$value};
        if ($numSeen >= $min && $numSeen <= $max)
        {
            if ($needLabel)
            {
                print "$label\n";
                $needLabel = 0;
            }
            print "$value\n";
        }
    }
}

printReport(0, 0, "Values missing:");
printReport(2, $numValues, "Values occurring more than once:");

