Wednesday, May 28, 2008

Google Treasure Hunt 2008: Puzzle 2 (zip) solution

Many have published one-liners for this. Just shows you how dense I am. Also, I was confused about the fact that the whole pathname, rather than just the filename (sans directory) should be matched. Whatever.


#!/usr/bin/perl -w

## Unzip the archive, then process the resulting files to obtain a
## numeric result. You'll be taking the sum of lines from files
## matching a certain description, and multiplying those sums together
## to obtain a final result. Note that files have many different
## extensions, like '.pdf' and '.js', but all are plain text files
## containing a small number of lines of text.
##
## Sum of line 5 for all files with path or name containing bar and ending in .pdf
## Sum of line 5 for all files with path or name containing def and ending in .rtf
## Hint: If the requested line does not exist, do not increment the sum.
##
## Multiply all the above sums together and enter the product below.
## (Note: Answer must be an exact, decimal representation of the number.)

use strict;

sub sumup_lines_n_from_files ($$);

my $dir = 'GoogleTreasureHunt08_8189817998309559603';

my $result = sumup_lines_n_from_files (1, '.*EFG.*\.js$')
* sumup_lines_n_from_files (4, '.*def.*\.js$');

print $result,"\n";
1;

sub sumup_lines_n_from_files ($$) {
my ($lineno, $re) = @_;
my $sum = 0;
open (FILES, "find $dir -print |")
or die "Cannot start find: $!";
while () {
chomp;
next unless /$re/x;
#warn "FOUND FILE: $_";
next unless -r $_;
open (FILE, $_) or die "open $_: $!";
my $l = 1;
while () {
chomp;
if ($l++ == $lineno) {
warn "line $lineno: $_";
$sum += $_;
}
}
close FILE or die "close $_: $!";
}
close FILES
or die "find $dir -name '$result': $!";
return $sum;
}

No comments: