These are the results of the PGA Golf Round 1.

Since the first round I've learned that Ronald Kimball, aka chipmunk, was one of the organisers of the the Perl Golf Apocalypse. He has also, very graciously, provided me with the commentary to the solutions below. Thanks Ronald. :-)

The full organising and judging committee of the Perl Golf Apocalypse were: Uri Guttman, Brand Hilton, Ronald Kimball, Larry Rosler and Damian Conway.

Special mention goes to tachyon who actually tried to complete the holes in the allotted time. A bottle of red wine thwarted his efforts however and he got 4 of the 6 holes wrong on the first pass. The motto there: "Don't drink and drive". :-|

ROUND 1: - Holes 1-6

Hole 1 - Fifth Word

Write a Perl subroutine which returns the fifth word in a string. A word is any sequence of letters, numbers, and/or underscores. The string will be passed as the sole argument and will contain at least 5 words.

* Difficulty: Easy

* Time: 3 minutes

* Solutions:
sub hole{(pop=~/\w+/g)[4]} # 16

* Commentary

This was intended as a practice hole for the tournament. This hole provides some hints to help with the later holes. If there's one argument in @_, pop is the shortest way to get at it; and many golf problems can be solved with a short regular expression.

This hole also shows how tricky these golf holes can be. A correct solution should return the word 'fifth' for the following string: '!first@@second#third$$fourth%fifth^^sixth'. In this string, the words are not broken by whitespace; the words are broken by multiple non-word characters; and the first word is preceeded by a non-word character.

Hole 2 - Error Message

Write a Perl one-liner that prints the following to STDERR:
Can't find label TPC at -e line 5.

* Difficulty: Easy

* Time: 3 minutes

* Solutions:
perl -e"die qq{Can't find label TPC at -e line 5.\n}" # 53 perl -e '' -e '' -e '' -e '' -e'goto TPC' # 41 perl -e0 -e, -e, -e';' -e'goto TPC' # 35 perl -e{ -e{ -e} -e} -e'goto TPC' # 33 perl -e'#line 5' -e'goto TPC' # 29 perl -e'#line 5' -egoto+TPC # 27

* Commentary

This hole was really just to see if people know about the somewhat obscure #line direction. It was used as a practice hole at the tournament.

We decided to disallow the following clever solution, because it's not strictly a one-liner. This solution works because sh allows quotes to span multiple lines.
perl -e" goto TPC"
jmcnamara: I actually counted solutions of this nature. The #line solution is interesting. I tried this but I added the -P switch because I thought it needed to be preprocessed. It doesn't.

Hole 3 - Smallest Repeating Pattern

Write a subroutine that accepts a string which may consist of a repeating pattern, and returns the smallest repeating substring. If the string does not consist of a repeating pattern, the subroutine should return undef or the empty string. e.g.:
input output 'aaaaaa' 'a' 'ababab' 'ab' 'aabaab' 'aab' 'ababaa' ''
* Difficulty: Easy

* Time: 4 minutes

* Solutions:
sub hole{pop=~/^(.+?)\1+$/;$1} #20

* Commentary

This hole is tricky, because the subroutine is being called in scalar context. Otherwise the result of the pattern match could be returned directly. The obvious way to work around that is with (pop=~/^(.+?)\1+$/)[0]) but changing to the solution shown above saves... one whole character! :)

A shorter solution is pop=~/^(.+?)\1+$/;$1 but that depends on $1 already being empty when the subroutine is called, which may not be the case. This possibility was accounted for in the test data at the conference.

jmcnamara: This was the hole that most people avoided.

Hole 4 - Hex to Char

Write a subroutine which, given a string consisting entirely of hexadecimal digits, converts pairs of digits to their ASCII character equivalents and returns the result as a list of characters. The hexadecimal digits A-F may appear in upper or lower case. There will be an even number of digits in the string. e.g.
5065726c206861636b6572 -> ('P', 'e', 'r', 'l', ' ', 'h', 'a', 'c', 'k', 'e', 'r')
* Difficulty: Easy

* Time: 4 minutes

* Solutions:
sub hole{grep$_=$_&&chr hex,split/(..)/,pop} # 34 sub hole{$_=pop;s/../chr hex$&/ge;/./g} # 29 sub hole{map{chr hex}pop=~/../g} # 32 sub hole{split//,pack'H*',@_} # 19 sub hole{(pack'H*',@_)=~/./g} # 19 sub hole{$_=pack'H*',@_;/./g} # 19

* Commentary

Ronald came up with this hole because he wanted to be clever with split and grep. Then someone posted one of the pack solutions. Doh! But he redeemed himself slightly by coming up with another of the pack variants shown above.

Hole 5 - Max without Sort

Write a subroutine that accepts a list of numbers, and returns the maximum number from the list, without using Perl's built-in sort.

* Difficulty: Easy

* Time: 4 minutes

* Solutions:
sub hole{$m=pop;$m=($m,$_)[$m<$_]for@_;$m} # 32 sub hole{$m=pop;$_>$m&&($m=$_)for@_;$m} # 29 sub hole{$m=pop;$_>$m?$m=$_:1for@_;$m} # 28

* Commentary

This one is a nice, straightforward golf problem. Except for one thing; a correct solution requires initializing max with an element of the list. Otherwise, the subroutine fails when all the elements are negative.

At the tournament, one team tried initializing max to -999,999, but that wasn't low enough to fool the judging script. Sorry, no points!

Hole 6 - Vowel Sort

Write a subroutine that accepts a list of words, and returns the list sorted by the first *vowel* that appears in each word. If two words have the same first vowel, it does not matter which is sorted first. Words will be in lowercase and will always contain at least one vowel. (Vowels are a, e, i, o, and u.)
e.g.: hole('dog', 'cat', 'fish', 'duck', 'lemur') returns: ('cat', 'lemur', 'fish', 'dog', 'duck')

* Difficulty: Easy

* Time: 5 minutes

* Solutions:
sub hole{map{$_->[0]}sort{$a->[1]cmp$b->[1]}map{[$_,m/[aeiou]/g]}@_} + # 58 sub hole{sort{($a=~/([aeiuo])/)[0]cmp($b=~/([aeiou])/)[0]}@_} # 51 sub hole{sort{($a=~($v='([aeiou])'))[0]cmp($b=~$v)[0]}@_} # 47 sub hole{map{substr$_,1}sort map{/[aeiou]/;$&.$_}@_} # 42 sub hole{map/.(.+)/,sort map/[aeiou]/&&$&.$_,@_} # 38

* Commentary

There are several possible approaches to this problem. The first solution above uses a classic Schwartzian Transform, a map sort map with array references. The second and third pull out the vowels every time the comparison sub is called; the third saves keystrokes by assigning the regex to a variable. The fourth and fifth use the method written about by Uri Guttman and Larry Rosler in their Sort::Fields paper; a map sort map using the default comparison function.


Replies are listed 'Best First'.
Re: PGA Golf, Round 1 - Results
by jmcnamara (Monsignor) on Jun 01, 2001 at 02:14 UTC

    Here is the leadership table after Round 1.

    Scores that equal or beat the best PGA score are shown in bold face. A penalty score, shown in red, is incurred if an incorrect solution was submitted or if no solution was submitted. The penalty is the maximum score on the hole +5. (If nothing else this will exercise the minds of the games theorists).

    I tested all the holes but not exhaustively. /msg me with any corrections.

    I've included anyone who tried any of the holes.

    Update: I need to fix some of the bold scores. Thanks tilly.

      1 2 3 4 5 6   1-6 7-12 13-17 Total
    Penalty 30 63 28 52 39 65   277     332
    Maximum 25 58 23 47 34 60   247     247
    Minimum 16 20 19 19 28 38   140     140
    PGA 16 27 20 19 28 38   148     148
    petral 16 20 19 19 30 38   142     142
    tilly 16 23 20 19 28 47   153     153
    japhy 16 23 23 19 29 47   157     157
    ChemBoy 18 24 22 19 30 44   157     157
    tadman 16 31 28 24 30 39   168     168
    mr.nick 21 24 28 32 32 51   188     188
    iamcal 16 63 28 26 39 42   214     214
    the_slycer 30 21 28 47 32 65   223     223
    tachyon 25 58 19 35 31 60   228     228
    da 30 21 28 52 39 65   235     235
    jorg 18 34 28 52 39 65   236     236
    btrott 30 63 28 20 39 48   228     228
    srawls 30 63 28 52 34 65   272     272

    Kudos to all those who participated.


      Most rounds of golf on pm seem to consist of several answers, along with (re: x 1..4)'s and updates, converging on the maximal(er, minimal) solution (which is great!).  And this one was no different, as I pointed out in my posting. My scores would have been *much* better if I hadn't seen the comments of fellow monks -- and wrong!
      That said, I still don't quite get it. Seems like everyone got hole 3 wrong, even if the official answer is also 'wrong' for certain not-explicitly-excluded edge conditions. (And most would have gotten 2 wrong.) (And... my fixed 5 was 32... and so on.)

      Anyway, the point is that this is such a different venue, that it's really a different sort of thing. Not that the score posting isn't fun anyway... I guess i'll just bring up a reply window from the 'New Meditations' page (so I can try for the lowest wrongest scores prize).


      update: Did I really say 'venue'? blecchhh...   (but I suppose it goes with Golf)

        You are right. The idea behind this is a bit flawed. The iterative approach to Golf as used in PerlMonks goes against the idea of a tournament. Also, as chipmunk pointed out here:

        We tried to make things a little easier at the actual tournament by providing a test scaffold for each hole, which the participants could use to test their code on sample input. Solving these holes is much harder without that.

        My main desire was to post some well conceived and well specified Golf questions as an example of how it should be done. In retrospect I should have just posted one a day and avoided the score tabulation. I might continue like that. I'll run it past the CB later.


Re: PGA Golf, Round 1 - Results
by japhy (Canon) on Jun 01, 2001 at 02:34 UTC
    I disagree on #3's minimum score, as seen by my comments in my answer:
    # 3 -- 23 chars # note: using $ instead of \z is *wrong* # note: using . without /s is *wrong* sub g3 { pop=~/^(.*?)\1+\z/s&&$1 }
    For that matter, par is 22:
    sub g3 { pop=~/^(.*?)\1+\z/s;$1 }

    japhy -- Perl and Regex Hacker
      Agreed. 22 is the best that I have.

      For a bit I mistakenly thought I had a 20 char solution in the form of:

      sub hole{map/^(.*?)\1+\z/s,@_}
      but the rules say that if a single thing is returned, then it will be in scalar context. In scalar context this solution is wrong (as I indicated in an "oops" update).
      Yup, this is another one of those tricky edge cases... which the committee missed completely! We forgot about newlines in the strings.

      I disagree on #3's minimum score, as seen by my comments in my answer:

      I noted this when you first posted it. I tried to account for it by adding 2 chars to the posts that had omitted \z and /s. However, I didn't get it right in all cases.

      Although, the PGA questions were well specified, it is always possible to miss a boundary condition like this. I should have modified the question to either make this requirement explicit or to specify that it wasn't required.


Re: PGA Golf, Round 1 - Results
by mtve (Deacon) on Sep 27, 2002 at 07:47 UTC

    Hole 6 can be improved by two chars:

    sub hole6{sort{$&x$a=~'[aeiuo]'cmp$&x$b=~//}@_}

    or, alternatively:

    sub hole6{sort{$a!~/[aeiuo]/.$&cmp$b!~//.$&}@_}