Raku: Advent of Code 2020 - Day Two

Below is a solution in Raku to the puzzle for Day Two.

I'm impressed by how clear, succinct, and expressive it is to code in Raku.

As you'll see below, regular expressions in Raku are not a write-only sub-language reminiscent of line-noise. A lot of thought went into improving the clarity and readability of regexes. By default whitespace is not syntacticially significant in a regex unless you declare it. This allows you to layout and format your regular expressions for readability.

token and rule are shorthand for named regexes with specific adverb modifiers applied. Tokens are regexes which do not ratchet (backtrack). And rules both don't ratchet _and_ treat whitespace as syntactically significant. 

The use of tokens and rules provide for named access to values within the returned match object.  Which as you'll see below is quite handy.

I haven't explored Grammars yet. But one can begin to see how grammars are only a hop, a skip, and a jump further on the learning curve. A learning curve which Raku has done a lot to flatten.

[02.raku]

use v6.d;

my token integer { <digit>+ }
my token minimum { <integer> }
my token maximum { <integer> }
my token hyphen { '-' }
my token match { <:alpha> }
my token colon { ':' }
my token password { <:alpha>+ }

my rule policy {
<minimum>
<hyphen>
<maximum>
<match>
}

my rule entry {
<policy>
<colon>
<password>
}

my @input = 'input'.IO.lines;

# Part One
my $valid_count = 0;
for @input -> $line {
if ($line ~~ /<entry>/) {
my ($min, $max, $match) = $<entry><policy><minimum maximum match>.map: { .Stringy };
my $password = ~$<entry><password>;
my $count = ($password ~~ m:g/$match/).elems;
if ($min <= $count <= $max) {
$valid_count++;
}
}
}
say "Part One: valid password count = $valid_count";

# Part Two
$valid_count = 0;
for @input -> $line {
if ($line ~~ /<entry>/) {
my ($pos1, $pos2, $match) = $<entry><policy><minimum maximum match>.map: { .Stringy };
my $password = ~$<entry><password>;
# adjust $pos1 and $pos2 from 1-indexing to 0-indexing
if ($password.substr-eq($match, --$pos1) xor $password.substr-eq($match, --$pos2)) {
$valid_count++;
}
}
}
say "Part Two: valid password count = $valid_count";

Comments

Popular posts from this blog

Raku: Setting up Raku (for Contributors)

Raku: Advent of Code 2020 - Day Twelve

Raku: Advent of Code 2020 - Day Thirteen