wc: Word Count

The goal for this Programming Praxis was to implement the Unix wc function. This one took me a couple days (I haven’t had a lot of time recently) to complete, but I finally finished it and this it works pretty good. It’s not a drop in replacement for wc, but it works – a programmers solution: by programmers, for programmers.

use Switch;

#print "arg num ". $#ARGV;
if ($#ARGV == -1) {
	usage();
}

@option;
@input;

#check first char of each argument
foreach $arg (@ARGV){
	if($arg =~ m/-.*/){
		@option = split //, $arg;
		#print "!".$arg."\n";
	}
	else{
		push(@input, $arg);
	}
}
#remove the "-" from the array
shift(@option);

foreach $input (@input){
	
	if(-e $input){
	#file exists, continue
		local( *FH ) ;
		open( FH, $input ) or die "sudden flaming death\n";
		$file = do { local( $/ ) ; <FH> };
		$fileSize = (-s $input);
		close(FH);
	}else{
		die("No such file or directory");
	}
	print "$input ";
	foreach $flag (@option){
		switch ($flag){
			
			case "c" {print "$fileSize "}
			case "m" {print length($file) . " "}
			case "l" {print $file =~ s/((^|\s)\S)/$1/g ." "}
			case "L" {print maxLineLength($input)." "}
			case "w" {print $file =~ s/(\n)/$1/g . " "}
			else {die ("invalid option -- $flag")}
		}
	}
	print "\n";
}

sub maxLineLength($input){
	my($thisInput) = @_;
	open(FH, $thisInput);
	$maxLine = 0;
	foreach $line (<FH>){
		if(length($line) > $maxLine){
			$maxLine = length($line);
		}
	}
	return $maxLine;
}

sub usage{

	print "Usage: wc [OPTION]... [FILE]...\n";
	print "  or:  wc [OPTION]... --files0-from=F\n";
	print "Print newline, word, and byte counts for each FILE, and a total line if\n";
	print "more than one FILE is specified.  With no FILE, or when FILE is -,\n";
	print "read standard input.\n";
	print "  -c            print the byte counts\n";
	print "  -m            print the character counts\n";
	print "  -l            print the newline counts\n";
	print "  -L, --max-line-length  print the length of the longest line\n";
	print "  -w, --words            print the word counts\n";
}

Autokey

On the recommendation of my friend Dan, I’m going to try to do some of these programming puzzles from time to time. I’m also going to try work these problems using Perl. Today’s assignment is to make a simple Autokey Cipher, which I accomplished over my lunch break.

use List::Util qw/sum/;

if ($#ARGV != 1 ) {
	print "usage: autokey.pl plainText key\n";
	exit;
}

$plainText = uc $ARGV[0];
$keyBase = uc $ARGV[1];

$key = $keyBase.$plainText;

print $key;

#$plainText	= "ACOLLECTIONOFETUDES";
#$key		= "PRAXISACOLLECTIONOF";
$cipherText	= "";

sub encipher{
	my($thisPlainText, $thisKey) = @_;

	#Clear Cipher'd text
	$thisCipherText = "";

	#Clear i
	$i=0;

	@arrayPlainText = split //, $thisPlainText;
	@arrayKey = split //, $thisKey;

	for($i = 0;  $i < scalar @arrayPlainText; $i++){
		if(@h{@arrayPlainText[$i]} + @h{@arrayKey[$i]} > 27){
			$thisCipherText .= @k[@h{@arrayPlainText[$i]} + @h{@arrayKey[$i]} - 27];
			#print @h{@arrayPlainText[$i]} + @h{@arrayKey[$i]} - 26 . "\n";
			#print @k[@h{@arrayPlainText[$i]} + @h{@arrayKey[$i]} - 26] . "\n";
		}
		else{
			$thisCipherText .= @k[@h{@arrayPlainText[$i]} + @h{@arrayKey[$i]} - 1];
			#print @h{@arrayPlainText[$i]} + @h{@arrayKey[$i]} . "\n";
			#print @k[@h{@arrayPlainText[$i]} + @h{@arrayKey[$i]}] . "\n";
		}

	}

	return $thisCipherText;

}

sub decipher{
	my($thisCipherText, $thisKey) = @_;

	@arrayCipherText = split //, $thisCipherText;
	@arrayKey = split //, $thisKey;

	for($i = 0;  $i < scalar @arrayCipherText; $i++){
		if(@h{@arrayCipherText[$i]} - @h{@arrayKey[$i]} < 0){
			$thisPlainText .= @k[@h{@arrayCipherText[$i]} - @h{@arrayKey[$i]} + 27];
		}
		else{
			$thisPlainText .= @k[@h{@arrayCipherText[$i]} - @h{@arrayKey[$i]} + 1];
		}
	}
	return $thisPlainText;
}

@h{'A' .. 'Z'} = (1 .. 26);
@k[1 .. 26] = ('A' .. 'Z');

$cipherText = &encipher($plainText, $key);

$decipherText = &decipher($cipherText, $key);

print " Plain text is: " . $plainText . "\n";
print "Cipher text is: " . $cipherText . "\n";
print "Decipher text is: " . $decipherText . "\n";