Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

For cheap thrills, I decided to have a go at replaying the original Santa Claus Golf Apocalypse with Pugs/Perl6. This note tells of my experiences attempting that.

Getting started with Pugs was a pleasingly simple two step process:

For more details on Pugs, go to pugscode.org.

All installed fine. Beauty. Now to write my first Perl 6 program, hello.p6:

say "Hello World!";
In bewildered awe and with shaking fingers, I entered:
pugs hello.p6
and back flashed the response:
Hello World!
Woo hoo! Now to work.

Please don't laugh at my original test program, tsanta.pl, written over three years ago. I decided to leave it alone in Perl 5 for now, just making the minor adjustment of running each golf hole with pugs rather than perl and changing the names of the programs from head.pl to head.p6 and so on. Maybe I'll try rewriting this test program in Perl 6 later. Update: The p6 rewrite, tsanta.p6, was done in Pugs Baby Steps; for latest versions of tsanta.p6 and rg0now's excellent solutions below see examples/golf in the Pugs distribution. Here is the updated 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 = "pugs $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.p6'; my $tail = 'tail.p6'; my $rev = 'rev.p6'; my $mid = 'mid.p6'; my $wc = 'wc.p6'; 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";

With that ugly chore out of the way, time to set about writing Perl 6 versions of each hole.

I started with Eugene's winning Perl 5 solutions from 2001, namely:

*** Eugene van der Pijll: 89 (11 19 13 25 21) *** --- head.pl --------------------------------------------- #!/usr/bin/perl -p 11..exit --- tail.pl --------------------------------------------- print+(<>)[-10..-1] --- rev.pl --------------------------------------------- #!/usr/bin/perl -p $\=$_.$\}{ --- mid.pl --------------------------------------------- #!/usr/bin/perl -p0 $_=$1while/.^(.+)^/ms --- wc.pl --------------------------------------------- printf"%010d\n",$.,<>

Now this is where I hit a bit of trouble as it dawned on me I had no idea how to write Perl 6 code. I further had no clue what parts of Perl 6 the scintillating autrijus had got around to implementing yet. Never fear, browse around the Pugs test suite a bit (while singing a song in praise of test-driven development) and grep for favourite functions, such as substr (nuts, not there), join (yep), elems (nuts again), reverse (oh dear), ...

Anyway, after a few hours of random hackery, I am the proud owner of five Pugs Perl 6 programs that pass the tsanta.pl test program. Here they are:

--- head.p6 --------------------------------------------- my$h=open@ARGS[0];print(($h.readline())[0..9]) --- tail.p6 --------------------------------------------- my$h=open@ARGS[0];my@l=$h.readline(); my$i;for(@l){++$i} $i=$i-10;$i=0 if$i<0; print@l[$i..Inf] --- rev.p6 --------------------------------------------- my$h=open@ARGS[0];my@l=$h.readline(); my$x;for(@l){$x=$_~$x} print$x; --- mid.p6 --------------------------------------------- # Note: works for Pugs 6.0.10 but will require removal # of -0.1 below for Pugs 6.0.11. my$h=open@ARGS[0];my@l=$h.readline(); my$i;for(@l){++$i} print@l[int(($i-1)/2-0.1)..int($i/2-0.1)] --- wc.p6 --------------------------------------------- my$h=open@ARGS[0];my@l=$h.readline(); my$i;for(@l){++$i} say join"",(split"",int(7e10+$i))[1..Inf];

Please note that these are not examples of good Perl 6 style -- quite the reverse actually, since I have no clue what I'm doing. Perl 6 experts, therefore, are invited to write much improved versions. In writing mid.p6, I noticed that int truncates in Perl 5 yet rounds in Pugs. Bug or feature? Update: It's a fixed bug (see autrijus journal) -- I was using Pugs 6.0.10 and version 6.0.11, due out in a couple of days, will include this truncate fix, which in turn will require a minor adjustment to mid.p6 (remove the silly -0.1 I think). Oh, and the lack of printf made wc.p6 a real pest to write.

Running: perl tsanta.pl produced:

You shot a round of 398 strokes. file1: running: 'pugs head.p6 in.tmp'...done (rc=0). file2: running: 'pugs head.p6 in.tmp'...done (rc=0). file3: running: 'pugs head.p6 in.tmp'...done (rc=0). file12: running: 'pugs head.p6 in.tmp'...done (rc=0). file1: running: 'pugs tail.p6 in.tmp'...done (rc=0). file2: running: 'pugs tail.p6 in.tmp'...done (rc=0). file3: running: 'pugs tail.p6 in.tmp'...done (rc=0). file12: running: 'pugs tail.p6 in.tmp'...done (rc=0). file21: running: 'pugs tail.p6 in.tmp'...done (rc=0). file1: running: 'pugs rev.p6 in.tmp'...done (rc=0). file2: running: 'pugs rev.p6 in.tmp'...done (rc=0). file3: running: 'pugs rev.p6 in.tmp'...done (rc=0). file21: running: 'pugs rev.p6 in.tmp'...done (rc=0). file1: running: 'pugs mid.p6 in.tmp'...done (rc=0). file2: running: 'pugs mid.p6 in.tmp'...done (rc=0). file3: running: 'pugs mid.p6 in.tmp'...done (rc=0). file4: running: 'pugs mid.p6 in.tmp'...done (rc=0). file12: running: 'pugs mid.p6 in.tmp'...done (rc=0). file21: running: 'pugs mid.p6 in.tmp'...done (rc=0). file1: running: 'pugs wc.p6 in.tmp'...done (rc=0). file2: running: 'pugs wc.p6 in.tmp'...done (rc=0). file3: running: 'pugs wc.p6 in.tmp'...done (rc=0). file4: running: 'pugs wc.p6 in.tmp'...done (rc=0). file12: running: 'pugs wc.p6 in.tmp'...done (rc=0). file21: running: 'pugs wc.p6 in.tmp'...done (rc=0). You shot a round of 398 strokes. Hooray, you passed.

Of course, everyone is invited to beat my pathetic score of 398 strokes and there are two ways to do this: download Pugs and write versions that pass the probing tsanta.pl test program; and (for Perl 6 gurus only) devise theoretically correct Perl 6 solutions that are not yet implemented in Pugs. Enjoy!


In reply to Replaying Santa Claus Golf Apocalypse with Pugs/Perl6 by eyepopslikeamosquito

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2024-04-19 07:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found