p2-util

Download the raw code.

class Point {
    has Num $.x;
    has Num $.y;
    my $num_re = rx{ \-? \d+ \. \d+ };
    method points ( Str $s ) {
        return gather for $s.split(' ') {
            / ^ ($num_re) \, ($num_re) $ /
                or say 'invalid input' and exit;
            take Point.new( x => +$0, y => +$1 );
        }
    }

    # This algorithm is a translation of pnpoly() from the
    # comp.graphics.algorithms FAQ question q2.03, "How do I find if a point
    # lies within a polygon?", http://www.faqs.org/faqs/graphics/algorithms-faq/
    # It returns True for strictly interior points, False for strictly exterior.
    # For points on the boundary, use a different algorithm.
    method in_poly ( $p: @ps ) returns Bool {
        my Bool  $c = False;
        my Point $j = @ps[*-1];
        for @ps -> Point $i {
            next unless $i.y <= $p.y < $j.y
                     or $j.y <= $p.y < $i.y;

            $c = !$c if $p.x <  $i.x 
                             + ($j.x - $i.x)
                             * ($p.y - $i.y)
                             / ($j.y - $i.y);
            $j = $i;
        }
        return $c;
    }
}

my @poly    = Point.points: $*IN.get;
my ($point) = Point.points: $*IN.get;

say $point.in_poly(@poly) ?? 'yes' !! 'no';

Readability

The code starts off with too few blank lines for my taste, but it quickly improves.

Consistency

exiting with a non-zero status would be preferable to exiting with a zero status, as the reason for exiting is invalid input. If not, might as well use die. (Except that's not an option here, because die in Rakudo outputs a backtrace no matter what you do -- "\n" trick from Perl 5 doesn't work -- and base-test is very specific about exactly what error message it wants.)

The code is a bit more tied to the particulars of the input format than I had in mind. Exactly one space between coordinate pairs, no whitespace between coordinates. I don't really feel entitled to nag about this part, though; I could easily have added a crazy test in base-test were I so inclined.

Clarity of intent

This solution has more explicit types than most of the others. It does make a difference.

Nice, natural use of a class Point. I like.

Algorithmic efficiency

Not really a concern with this task. Clearly linear. No pun intended.

Idiomatic use of Perl 6

The semantics of $num_re on line 4 -- yes, this is the same complaint as with another contestant's code -- is already provided by STD and Rakudo as dec_number (except for the minus sign). Notice how dec_number also considers two cases of decimal numbers that $num_re doesn't. It's my personal opinion, but reinventing parsing wheels should be fairly stigmatized.

The $j = $i on line 29 (along with its accomplice at line 20) feels like a poor man's zipped for loop. Simple, but not exactly playing to the strengths of Perl 6.

The gather on line 6 is nice, but should probably have been a map instead. Or just a for loop without an explicit return, though that might be a bit too subtle.

Brevity

The code is short and to the point.