# This is my favorite problem of the five. # I plan to write a talk around this, to show off this cool feature. class InExRange { has $.type; # Is + or - for inclusion or exclusion. has $.range; method new ( $type, $start, $stop ) { my $range = $start .. $stop; self.bless: *, :$type, :$range; } # Int, because smartmatch against range in silently # buggy if LHS is accidentally Str. method in_range ( Int $num ) { given self.type { return ? ( $num ~~ self.range ) when '+'; return ? ( $num !~~ self.range ) when '-'; die "Can't happen"; } } } grammar Range::Grammar { token TOP { \n* + } token start { \d+ } token stop { \d+ } token type { <[+\-]> } rule expr { '[' '..' ']' } } class Range::Actions { method TOP ( $/ ) { make $ยป.ast } method expr ( $/ ) { make InExRange.new: ~$, +$, +$ } } my ( $ranges_line, $num ) = $*IN.lines; $num ~~ /\d+/ or say 'invalid input' and exit; my $match = Range::Grammar.parse( $ranges_line, actions => Range::Actions.new ) or say 'no' and exit; my @ranges = $match.ast.list; say all(@ranges).in_range($num.Int) ?? 'yes' !! 'no';