#!/usr/bin/env raku # Password grammar was taken from tyil's solution. grammar Password { rule TOP { '-' ':' } token num { \d+ } token letter { \w } token password { \w+ } } sub MAIN ( # Part to run. Int $part where * == 1|2 = 1 ) { my $valid_passwords = 0; for "input".IO.lines -> $entry { if Password.parse($entry) -> $match { if $part == 1 { my %chars; $match.comb.map({ %chars{$_}++ }); # Check if the letter exists in the password. next unless %chars{$match}; # Check for length. next unless $match[0].Int <= %chars{$match}; next unless %chars{$match} <= $match[1].Int; } elsif $part == 2 { my $combed = $match.comb; my $first = $match[0].Int - 1; my $second = $match[1].Int - 1; next if $combed[$first] eq $combed[$second]; next unless $combed[$first] eq $match || $combed[$second] eq $match; } # All checks were completed & this is a valid password. $valid_passwords++; } } say "Part $part: " ~ $valid_passwords; }