diff options
author | Andinus <andinus@nand.sh> | 2020-12-04 19:06:44 +0530 |
---|---|---|
committer | Andinus <andinus@nand.sh> | 2020-12-04 19:06:44 +0530 |
commit | f2da3d2696546d1b12e9eb6a30bab31fefbba4ee (patch) | |
tree | 714a3126d44c84c7f40de901549eb62503a102f3 /2020/day-02/README.org | |
parent | cf9103e808531eb90b9a22668e655290732679d0 (diff) | |
download | aoc-f2da3d2696546d1b12e9eb6a30bab31fefbba4ee.tar.gz |
Add day-02 solution
Diffstat (limited to '2020/day-02/README.org')
-rw-r--r-- | 2020/day-02/README.org | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/2020/day-02/README.org b/2020/day-02/README.org new file mode 100644 index 0000000..93b1af0 --- /dev/null +++ b/2020/day-02/README.org @@ -0,0 +1,133 @@ +#+SETUPFILE: ~/.emacs.d/org-templates/level-3.org +#+HTML_LINK_UP: ../../../writings/#aoc +#+OPTIONS: toc:2 +#+EXPORT_FILE_NAME: index +#+TITLE: Day 02 - Password Philosophy + +* Puzzle +- This puzzle is taken from: https://adventofcode.com/2020/day/2 + +Your flight departs in a few days from the coastal airport; the easiest +way down to the coast from here is via toboggan. + +The shopkeeper at the North Pole Toboggan Rental Shop is having a bad +day. "Something's wrong with our computers; we can't log in!" You ask if +you can take a look. + +Their password database seems to be a little corrupted: some of the +passwords wouldn't have been allowed by the Official Toboggan Corporate +Policy that was in effect when they were chosen. + +To try to debug the problem, they have created a list (your puzzle +input) of passwords (according to the corrupted database) and the +corporate policy when that password was set. + +For example, suppose you have the following list: +#+BEGIN_SRC +1-3 a: abcde +1-3 b: cdefg +2-9 c: ccccccccc +#+END_SRC + +Each line gives the password policy and then the password. The password +policy indicates the lowest and highest number of times a given letter +must appear for the password to be valid. For example, 1-3 a means that +the password must contain a at least 1 time and at most 3 times. + +In the above example, 2 passwords are valid. The middle password, cdefg, +is not; it contains no instances of b, but needs at least 1. The first +and third passwords are valid: they contain one a or nine c, both within +the limits of their respective policies. + +How many passwords are valid according to their policies? +** Part 2 +While it appears you validated the passwords correctly, they don't seem +to be what the Official Toboggan Corporate Authentication System is +expecting. + +The shopkeeper suddenly realizes that he just accidentally explained the +password policy rules from his old job at the sled rental place down the +street! The Official Toboggan Corporate Policy actually works a little +differently. + +Each policy actually describes two positions in the password, where 1 +means the first character, 2 means the second character, and so on. (Be +careful; Toboggan Corporate Policies have no concept of "index zero"!) +Exactly one of these positions must contain the given letter. Other +occurrences of the letter are irrelevant for the purposes of policy +enforcement. + +Given the same example list from above: + +- =1-3 a: abcde= is valid: position 1 contains a and position 3 does not. +- =1-3 b: cdefg= is invalid: neither position 1 nor position 3 contains b. +- =2-9 c: ccccccccc= is invalid: both position 2 and position 9 contain c. + +How many passwords are valid according to the new interpretation of the +policies? +* Solution +Raku grammar is used to parse the file. I took the grammar from [[https://git.tyil.nl/advent-of-code/tree/2020/02.raku][tyil]]'s +solution. +#+BEGIN_SRC raku +# Password grammar was taken from tyil's solution. +grammar Password { + rule TOP { <num> '-' <num> <letter> ':' <password> } + token num { \d+ } + token letter { \w } + token password { \w+ } +} +#+END_SRC + +The program takes a positional input =$part= which instructs it on which +part it should solve. The default is to solve for part 1. + +=$valid_passwords= stores the number of passwords that are considered +valid. The checks are made inside the =if/elsif= loop & it continues from +there only if the password is considered valid. +#+BEGIN_SRC raku +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 { + ... + } elsif $part == 2 { + ... + } + # All checks were completed & this is a valid password. + $valid_passwords++; + } + } + say "Part $part: " ~ $valid_passwords; +} +#+END_SRC + +Nothing fancy is done, we just count the number of times each character +is used & then perform the check. +#+BEGIN_SRC raku +my %chars; +$match<password>.comb.map({ %chars{$_}++ }); + +# Check if the letter exists in the password. +next unless %chars{$match<letter>}; + +# Check for length. +next unless $match<num>[0].Int <= %chars{$match<letter>}; +next unless %chars{$match<letter>} <= $match<num>[1].Int; +#+END_SRC +** Part 2 +This part too just performs the check. +#+BEGIN_SRC raku +elsif $part == 2 { + my $combed = $match<password>.comb; + my $first = $match<num>[0].Int - 1; + my $second = $match<num>[1].Int - 1; + + next if $combed[$first] eq $combed[$second]; + next unless $combed[$first] eq $match<letter> || $combed[$second] eq $match<letter>; +} +#+END_SRC |