# p2-matthias

``````use v6;

# sliding-window() with possibility to adjust the sliding-speed:
sub sliding-window(@scenery, \$width, \$speed) {
gather for 0, \$speed  ...^  * > +@scenery - \$width  -> \$pos {
take @scenery[ \$pos .. \$pos + \$width - 1 ];
}
}

my regex number { '-'? \d+ '.' \d+ }
my  @polygon  = \$*IN.get.comb: /<&number>/;
my (\$px, \$py) = \$*IN.get.comb: /<&number>/;

if +@polygon < 6 || +@polygon % 2  or  ! defined (\$px && \$py) {
say 'invalid input';
exit;
}

# now, let us count the intersections of a straight line going down from the
# point in question, and the polygon's edges.

@polygon.push: @polygon[0,1];           # so that we get the Pn->P1 edge
my \$intersections = 0;
my \$ON_OUTLINE    = 0;                  # should be: my constant \$ON_OUTLINE

for sliding-window(@polygon, 4, 2) -> \$ax, \$ay, \$bx, \$by {
next if \$ay & \$by  >  \$py           # skip upper edges
or \$ax & \$bx  <  \$px           # skip left edges
or \$ax & \$bx  >  \$px;          # skip right edges

# function representing the edge: Ey(x) = mx + b

if \$bx - \$ax -> \$dx {
my \$m = (\$by - \$ay) / \$dx;
my \$b = \$ay - \$m * \$ax;

given \$m * \$px + \$b {
when * <  \$py { ++\$intersections }
when * == \$py {
\$intersections = \$ON_OUTLINE;
last;
}
}
}
elsif \$ay | \$by  >  \$py {
\$intersections = \$ON_OUTLINE;
last;
}
}

say \$intersections % 2 ?? 'yes' !! 'no';
``````

Clearly laid out. Names are either understandable or explained.

## Consistency

It wasn't required anywhere, but `exit`ing with a non-zero status would be preferable if the reason for exiting is invalid input. People didn't use `die` because of the constraints `base-test` put up; but doing a normal `exit` still feels wrongish.

## Clarity of intent

The cases in the main loop are not well explained, but at least fairly easy to follow.

This solution stores coordinates flat inside an array, staggering `x` and `y` coordinates. It's less of a data structure overhead than the other solutions, but no less worthy of a comment.

## Algorithmic efficiency

Not much of a concern in this problem. The solution is clearly linear on the number of points.

## Idiomatic use of Perl 6

Generally nice use of junctions to simplify condition expressions in this one.

TimToady++ pointed out a nice Perl 6 idiom that I stared at but managed to miss: the `if \$bx - \$ax -> \$dx { ... }` on line 33. Clearly an appropriate use of the lambda arrow.

The semantics of the regex `number` on line 10... 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 `number` doesn't. It's my personal opinion, but reinventing parsing wheels should be fairly stigmatized.

## Brevity

The solution is nice and short.