aboutsummaryrefslogtreecommitdiff
path: root/2020/day2.raku
blob: f3952dee7d2afa7ff78684aeb4f6cbdb7d9e214f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use v6;

#use Grammar::Tracer;
#`{
1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc
}
grammar Password {
    token TOP { <lines>+ }
    token lines { ^^ <constraints> ' ' <char> ': ' <password> \n }
    token constraints { $<from> = [ \d+ ] '-' $<to> = [ \d+ ] }
    token char { \w }
    token password { <.alnum>+ }
}

class Part1Actions {
    method TOP($/) { make $<lines>.grep(*.made.so).elems }
    method lines($/) { make $<password>.comb($<char>).elems$<constraints>.made }
    method constraints($/) { make $<from> .. $<to> }
}

class Part2Actions {
    method TOP($/) { make $<lines>.grep(*.made.so).elems }
    method lines($/) {
        make
        $.has-str($<password>.made, $<char>.made, $<constraints><from>.Int)
        ?^
        $.has-str($<password>.made, $<char>.made, $<constraints><to>.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<lines>[0].made;

        is $g.made, 2, 'Example';
    }

    subtest 'Part2', {
        my $g = Password.parse($input, actions => Part2Actions.new);
        say $g<lines>[0].made;

        is $g.made, 1, 'Example';
    }
}