#!/usr/bin/perl -w
###########################################################
# Count how many times each word appears in a given file.  
#
# A hash table example for Algorithms class.  
# For the terse version, see count2.pl
# 
# Usage:
#        ./countWords.pl > countWords.out
# 
#   v1.0 10/22/02
#   Jim Mahoney (mahoney@marlboro.edu)
###########################################################
use strict;
use Time::HiRes qw(gettimeofday tv_interval);   # Timing routines.

my $VERSION = "countWords.pl 1.0";
my $iManyOut = 50;				# Number of words to print out.
my $filename = "bskrv10.txt";			# Input file name.
my $lineNumber=0;
my $totalWords=0;
my %wordCounts;					# Hash to count word occurances.

print " --- '$VERSION' --- \n";
print " Input file is '$filename'. \n";

open(INPUT,$filename)				# Open the file.
  or die "Oops.  Couldn't open '$filename'";	# If there's a problem, exit with an error. 

my $startTime = [gettimeofday];
print " Counting words... ";
while (my $line = <INPUT>) {			# Loop over the lines in the file
  $lineNumber++;
  #print " line = '$line'\n";			#       (debugging - show current line)

  my @words = split /[^a-zA-Z\-_]/, $line;	#	Extract "words" made of ( a-z A-Z - _ )
  #print " words = (",join(",",@words),")\n";	#       (debugging - show words in line)

  foreach my $word (@words) {			#	Loop over words.
    $word = lc($word);				#		Convert to lowercase.
    $wordCounts{$word}++ if $word;		#		Increment hash entry.
    $totalWords++ if $word;			#		Count total words seen.
  }
  #die " 20 lines " if $lineNumber>20		#               (debugging - exit at line 20)
}
print " done. (" . tv_interval($startTime) . " sec) \n";

						# Output results alphabetically.
$startTime = [gettimeofday];
print " Sorting list alphabetically...";
my @wordList = sort keys %wordCounts;
print " done. (" . tv_interval($startTime) . " sec) \n";

print " Examined $totalWords words in $lineNumber lines.\n";
print " Found " . scalar(@wordList) . " different words. \n";
print " First $iManyOut word counts, sorted alphabetically by word : \n";
for (my $i=0; $i<$iManyOut; $i++){
  printf(" %4d  %-30s  %10d \n", $i+1, $wordList[$i], $wordCounts{$wordList[$i]});
}

						# Output results sorted by word frequency.
$startTime = [gettimeofday];
print " Sorting list by word count...";
@wordList = sort { $wordCounts{$b} <=> $wordCounts{$a} } keys %wordCounts;
print " done. (" . tv_interval($startTime) . " sec) \n";

print " First $iManyOut word counts,  sorted by word frequency : \n";
for (my $i=0; $i<$iManyOut; $i++){
  printf(" %4d  %-30s  %10d \n", $i+1, $wordList[$i], $wordCounts{$wordList[$i]});
}

print "\n So there you are.\n";


