LA.pm: The Santa Claus Golf Apocalypse

Robert Spier rspier at pobox.com
Sun Dec 2 20:00:14 CST 2001


Anyone interested in playing along?  We could have a mini la-pm
competition, where the winner gets dinner, or a drink or something.

-R

    * To: fwp at perl.org
    * Subject: The Santa Claus Golf Apocalypse
    * From: Andrew.Savige at ir.com
    * Date: Sun, 2 Dec 2001 19:40:37 +1100
    * Delivered-To: mailing list fwp at perl.org
    * Mailing-List: contact fwp-help at perl.org; run by ezmlm

As an early Christmas present, you are invited to play
Santa Claus' newly constructed 5-hole golf course.

The holes are likely too easy, but that will hopefully
encourage more entries (feedback welcome). In fact,
this whole golf game is a little experimental and
hopefully we can improve its format based on the
outcome of this game.

Please post solutions only to me, Santa the Arbiter.
But before posting, verify your entries with the below
test program, tsanta.pl. I will verify that they are
indeed ok and post a daily leaderboard. I am open to
ideas re the winner's prize.

In most fwp golf games, we all steal ideas; the idea
here is to keep the source code secret, only the
current leaderboard is known.

The test program, tsanta.pl, should run on both Windows
and Unix (forgive me, but I don't have a Unix machine
available right now). To allow for cross-platform
differences, please format your code with a leading
#!/usr/bin/perl line if you want to use command-line
switches. For example:
#!/usr/bin/perl -n
print
This has golf score of 8 (5 for 'print', 3 for ' -n').

All 5 holes manipulate text files. You may assume that
said text files are always properly newline-terminated
and that they do not contain any binary zeros.
Similarly, your programs must properly newline-terminate
everything they write (they always write to stdout).
When in doubt about the specification, use the test
program, tsanta.pl; if your entries pass the test
program, they are ok.

You must name your programs as shown below and put
them in the same directory as the test program.
That done, run the test program:
  perl tsanta.pl
to verify that your entries meet the specification.

Hole 1.  head.pl. Print first 10 lines of a text file.

Hole 2.  tail.pl. Print last 10 lines of a text file.

Hole 3.  rev.pl.  Print a text file in reverse order.

Hole 4.  mid.pl.  Print the middle line/s of a text file
                  (one line if an odd number of lines;
                   two lines if an even number).

Hole 5.  wc.pl.   Print the number of lines in the file to
                  stdout, zero-filled, right-justified,
                  10 chars wide.

Merry Christmas to all participants.
Santa Claus the Arbiter.

test program, tsanta.pl
-----------------------
# tsanta.pl. Santa Claus golf game test program.
use strict;

sub GolfScore {
   my $script = shift;
   open(FF, $script) or die "error: open '$script'";
   my $golf = 0;
   while (<FF>) {
      chomp; next unless length;
      s/^#!.*?perl// if $. == 1;
      $golf += length;
   }
   close(FF);
   return $golf;
}

sub PrintGolfScore {
   my @scr = @_;
   my $tot = 0;
   for my $s (@scr) { $tot += GolfScore($s) }
   print "You shot a round of $tot strokes.\n";
}

sub BuildFile {
   my ($fname, $data) = @_;
   open(FF, '>'.$fname) or die "error: open '$fname'";
   print FF $data;
   close(FF);
}

sub CheckOne {
   my ($scr, $label, $data, $exp) = @_;
   my $intmp  = 'in.tmp';
   BuildFile($intmp, $data);
   my $cmd = "perl $scr $intmp";
   print "$label: running: '$cmd'...";
   my $out = `$cmd`; my $rc = $? >> 8;
   print "done (rc=$rc).\n";
   if ($out ne $exp) {
      warn "Expected:\n"; print STDERR $exp;
      warn "Got:\n"; print STDERR $out;
      die "Oops, you failed.\n";
   }
}

# -----------------------------------------------------

my $file1 = <<'GROK';
1st line
GROK

my $file2 = <<'GROK';
1st line
2nd line
GROK

my $file3 = <<'GROK';
1st line
2nd line
3rd line
GROK

my $file4 = <<'GROK';
1st line
2nd line
3rd line
4th line
GROK

my $file12 = <<'GROK';
1st line
2nd line
3rd line
4th line
5th line
6th line
7th line
8th line
9th line
10th line
11th line
12th line
GROK

my $file21 = <<'GROK';
1st line
2nd line
3rd line
4th line
5th line
6th line
7th line
8th line
9th line
10th line
11th line
12th line









GROK

# -----------------------------------------------------

sub CheckHead {
   my ($scr) = @_;
   my @tt = (
      [ 'file1',  $file1,  "1st line\n" ],
      [ 'file2',  $file2,  "1st line\n2nd line\n" ],
      [ 'file3',  $file3,  "1st line\n2nd line\n3rd line\n" ],
      [ 'file12', $file12,
        "1st line\n2nd line\n3rd line\n4th line\n5th line\n".
        "6th line\n7th line\n8th line\n9th line\n10th line\n" ],
   );
   for my $r (@tt) { CheckOne($scr, $r->[0], $r->[1], $r->[2]) }
}

sub CheckTail {
   my ($scr) = @_;
   my @tt = (
      [ 'file1',  $file1,  "1st line\n" ],
      [ 'file2',  $file2,  "1st line\n2nd line\n" ],
      [ 'file3',  $file3,  "1st line\n2nd line\n3rd line\n" ],
      [ 'file12', $file12,
        "3rd line\n4th line\n5th line\n6th line\n7th line\n".
        "8th line\n9th line\n10th line\n11th line\n12th line\n" ],
      [ 'file21', $file21, "12th line\n\n\n\n\n\n\n\n\n\n" ],
   );
   for my $r (@tt) { CheckOne($scr, $r->[0], $r->[1], $r->[2]) }
}

sub CheckRev {
   my ($scr) = @_;
   my @tt = (
      [ 'file1',  $file1,  "1st line\n" ],
      [ 'file2',  $file2,  "2nd line\n1st line\n" ],
      [ 'file3',  $file3,  "3rd line\n2nd line\n1st line\n" ],
      [ 'file21', $file21,
        "\n\n\n\n\n\n\n\n\n12th line\n11th line\n10th line\n".
        "9th line\n8th line\n7th line\n6th line\n5th line\n".
        "4th line\n3rd line\n2nd line\n1st line\n" ],
   );
   for my $r (@tt) { CheckOne($scr, $r->[0], $r->[1], $r->[2]) }
}

sub CheckMid {
   my ($scr) = @_;
   my @tt = (
      [ 'file1',  $file1,  "1st line\n" ],
      [ 'file2',  $file2,  "1st line\n2nd line\n" ],
      [ 'file3',  $file3,  "2nd line\n" ],
      [ 'file4',  $file4,  "2nd line\n3rd line\n" ],
      [ 'file12', $file12, "6th line\n7th line\n" ],
      [ 'file21', $file21, "11th line\n" ],
   );
   for my $r (@tt) { CheckOne($scr, $r->[0], $r->[1], $r->[2]) }
}

sub CheckWc {
   my ($scr) = @_;
   my @tt = (
      [ 'file1',  $file1,  "0000000001\n" ],
      [ 'file2',  $file2,  "0000000002\n" ],
      [ 'file3',  $file3,  "0000000003\n" ],
      [ 'file4',  $file4,  "0000000004\n" ],
      [ 'file12', $file12, "0000000012\n" ],
      [ 'file21', $file21, "0000000021\n" ],
   );
   for my $r (@tt) { CheckOne($scr, $r->[0], $r->[1], $r->[2]) }
}

# -----------------------------------------------------

my $head = 'head.pl';
my $tail = 'tail.pl';
my $rev  = 'rev.pl';
my $mid  = 'mid.pl';
my $wc   = 'wc.pl';
select(STDERR);$|=1;select(STDOUT);$|=1;  # auto-flush
-f $head or die "error: file '$head' not found.\n";
-f $tail or die "error: file '$tail' not found.\n";
-f $rev  or die "error: file '$rev' not found.\n";
-f $mid  or die "error: file '$mid' not found.\n";
-f $wc   or die "error: file '$wc' not found.\n";
PrintGolfScore($head, $tail, $rev, $mid, $wc);
CheckHead($head);
CheckTail($tail);
CheckRev($rev);
CheckMid($mid);
CheckWc($wc);
PrintGolfScore($head, $tail, $rev, $mid, $wc);
print "Hooray, you passed.\n";


-- 




More information about the Losangeles-pm mailing list