use v6; #use Grammar::Tracer; #`{ 1-3 a: abcde 1-3 b: cdefg 2-9 c: ccccccccc } grammar Password { token TOP { + } token lines { ^^ ' ' ': ' \n } token constraints { $ = [ \d+ ] '-' $ = [ \d+ ] } token char { \w } token password { <.alnum>+ } } class Part1Actions { method TOP($/) { make $.grep(*.made.so).elems } method lines($/) { make $.comb($).elems ∈ $.made } method constraints($/) { make $ .. $ } } class Part2Actions { method TOP($/) { make $.grep(*.made.so).elems } method lines($/) { make $.has-str($.made, $.made, $.Int) ?^ $.has-str($.made, $.made, $.Int) } method password($/) { make $/.Str } method char($/) { make $/.Str } method has-str(Str $password, Str $char, Int $offset --> Bool) { $password.substr-eq($char, $offset - 1) } } multi sub MAIN('part1', $file) { say Password.parse(slurp($file), actions => Part1Actions.new).made; } multi sub MAIN('part2', $file) { say Password.parse(slurp($file), actions => Part2Actions.new).made; } multi sub MAIN('test') { use Test; my $input = q:to/END/; 1-3 a: abcde 1-3 b: cdefg 2-9 c: ccccccccc END subtest 'Part1', { my $g = Password.parse($input, actions => Part1Actions.new); say $g[0].made; is $g.made, 2, 'Example'; } subtest 'Part2', { my $g = Password.parse($input, actions => Part2Actions.new); say $g[0].made; is $g.made, 1, 'Example'; } }