use v6; use Test; # p3 solution by colomon grammar InclusionsAndExclusions { regex integer { '-'? + } regex inclusion { '+[' '..' ']' } regex exclusion { '-[' '..' ']' } regex in_or_ex { | } regex TOP { ^ * $ } } sub make-range($clusion) { (+$clusion[0]) .. (+$clusion[1]); } sub test-inclusions-and-exclusions(Str $intervals, Int $integer) { my $cleaned-intervals = $intervals.subst(/\h+/, "", :global); my $match = InclusionsAndExclusions.parse($cleaned-intervals, :rule); return Bool unless $match; my $result = Bool::False; for @($match) -> $in-or-ex { if $in-or-ex { $result = Bool::True if $integer ~~ make-range($in-or-ex); } else { $result = Bool::False if $integer ~~ make-range($in-or-ex); } } $result; } multi MAIN() { my $intervals = $*IN.get; my $integer = $*IN.get.Int; my $result = test-inclusions-and-exclusions($intervals, $integer); say $result.defined ?? $result ?? "yes" !! "no" !! "invalid input"; } multi MAIN("test") { plan *; { my $match = InclusionsAndExclusions.parse("+[1..10]", :rule); isa_ok $match, Match, "We matched"; is $match[0], 1, "Start is 1"; is $match[1], 10, "End is 10"; } { my $match = InclusionsAndExclusions.parse("-[1..10]", :rule); isa_ok $match, Match, "We matched"; is $match[0], 1, "Start is 1"; is $match[1], 10, "End is 10"; } { my $match = InclusionsAndExclusions.parse("-[1..10]+[2..4]", :rule); isa_ok $match, Match, "We matched"; ok $match[0], "First match is an exclusion"; nok $match[0], "First match is not an inclusion"; ok $match[1], "Second match is an inclusion"; nok $match[1], "Second match is not an exclusion"; } ok test-inclusions-and-exclusions("+[1..10]", 4), "4 is in 1..10"; nok test-inclusions-and-exclusions("+[1..10]-[2..4]", 4), "4 is not in +[1..10]-[2..4]"; nok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 41), "41 not in masak's example"; ok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 42), "42 in masak's example"; ok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 47), "47 in masak's example"; ok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 49), "49 in masak's example"; nok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 50), "50 not in masak's example"; nok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 55), "55 not in masak's example"; nok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 60), "60 not in masak's example"; ok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 61), "61 in masak's example"; ok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 80), "80 in masak's example"; ok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 100), "100 in masak's example"; nok test-inclusions-and-exclusions("+[ 42 .. 100 ] -[ 50 .. 60 ] -[ -10 .. 2 ]", 101), "101 not in masak's example"; nok test-inclusions-and-exclusions("+", 4).defined, "Recognized illegal input"; done; }