# p2-util

``````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';
``````

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

## Consistency

`exit`ing with a non-zero status would be preferable to `exit`ing 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.