diff options
author | Matias Linares <matiaslina@gmail.com> | 2020-12-08 13:11:18 -0300 |
---|---|---|
committer | Matias Linares <matiaslina@gmail.com> | 2020-12-08 13:11:18 -0300 |
commit | 1d6085cd7dfb5d75b89ccf2edd950afec3665f24 (patch) | |
tree | 231c3b84f6fc347e07a456468e2f525bf9836a8b /2020/day4.raku | |
parent | 8c6b7ffc7e0e27ddfa1c6ee51a69dbfbd752d8dd (diff) | |
download | advent-of-code-1d6085cd7dfb5d75b89ccf2edd950afec3665f24.tar.gz |
Add day 4
Diffstat (limited to '2020/day4.raku')
-rw-r--r-- | 2020/day4.raku | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/2020/day4.raku b/2020/day4.raku new file mode 100644 index 0000000..1790de4 --- /dev/null +++ b/2020/day4.raku @@ -0,0 +1,146 @@ +#!/usr/bin/env raku + +constant \EXAMPLE = q:to/END/; +ecl:gry pid:860033327 eyr:2020 hcl:#fffffd +byr:1937 iyr:2017 cid:147 hgt:183cm + +iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884 +hcl:#cfa07d byr:1929 + +hcl:#ae17e1 iyr:2013 +eyr:2024 +ecl:brn pid:760753108 byr:1931 +hgt:179cm + +hcl:#cfa07d eyr:2025 pid:166559648 +iyr:2011 ecl:brn hgt:59in +END + +constant \required-keys = <byr iyr eyr hgt hcl ecl pid>; + +sub split-input($input) { + $input.split: /^^$$/; +} + +sub valid-passport($passport --> Bool) { + [&&] required-keys.map({ $passport.contains($_) }) +} + +sub valid-passports($input) { + split-input($input).grep(*.&valid-passport) +} + +# Data Validation + +my %validations = ( + byr => sub ($v) { 1920 <= $v <= 2002 }, + iyr => sub ($v) { 2010 <= $v <= 2020 }, + eyr => sub ($v) { 2020 <= $v <= 2030 }, + hgt => sub ($v) { + if $v ~~ m/$<height> = [\d+] $<unit> = [ cm || in ]/ { + if $<unit> eq 'cm' { return 150 <= $<height> <= 193 } + else { return 59 <= $<height> <= 76 } + } + False + }, + hcl => sub ($v) { so $v ~~ m/'#' <[0..9 a..f]> ** 6/ }, + ecl => sub ($v) { so $v ~~ m/amb || blu || brn || gry || grn || hzl || oth/ }, + pid => sub ($v) { so $v ~~ m/^^\d ** 9 $$/ }, + cid => { True } +); + +sub data-validation($passport) { + [&&] $passport.words».split(':').map( + -> ($k, $v) { + %validations{$k}($v) + } + ) +} + +multi sub MAIN('part1', $file) { + say valid-passports(slurp($file)).elems; +} + +multi sub MAIN('part2', $file) { + say +valid-passports(slurp($file)).grep({ $_.&data-validation}) +} + +multi sub MAIN('test') { + use Test; + subtest 'Part1', { + is split-input(EXAMPLE).elems, 4, 'length'; + ok valid-passport(split-input(EXAMPLE)[0]), 'first input'; + nok valid-passport(split-input(EXAMPLE)[1]), 'second input'; + ok valid-passport(split-input(EXAMPLE)[2]), 'third input'; + nok valid-passport(split-input(EXAMPLE)[3]), 'four input'; + + is valid-passports(EXAMPLE).elems, 2, 'validate-passports'; + }; + subtest 'Part 2', { + subtest 'byr', { + ok %validations<byr>('2002'), 'valid'; + nok %validations<byr>('2003'), 'invalid'; + }; + subtest 'hgt', { + ok %validations<hgt>('60in'), 'valid in'; + ok %validations<hgt>('190cm'), 'valid cm'; + nok %validations<hgt>('190in'), 'invalid in'; + nok %validations<hgt>('190'), 'invalid'; + }; + subtest 'hcl', { + ok %validations<hcl>('#123abc'), 'valid'; + nok %validations<hcl>('#123abz'), 'invalid'; + nok %validations<hcl>('123abc'), 'missing #'; + }; + subtest 'ecl', { + ok %validations<ecl>('brn'), 'valid'; + nok %validations<ecl>('wat'), 'invalid'; + } + subtest 'pid', { + ok %validations<pid>('000000001'), 'valid'; + nok %validations<pid>('0123456789'), 'valid'; + } + + subtest 'data validation', { + my $invalid-data = q:to/END/; + eyr:1972 cid:100 + hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926 + + iyr:2019 + hcl:#602927 eyr:1967 hgt:170cm + ecl:grn pid:012533040 byr:1946 + + hcl:dab227 iyr:2012 + ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277 + + hgt:59cm ecl:zzz + eyr:2038 hcl:74454a iyr:2023 + pid:3556412378 byr:2007 + END + + for split-input($invalid-data).kv -> $i, $passport { + nok data-validation($passport), "Run invalid $i"; + } + + my $valid-data = q:to/END/; + pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980 + hcl:#623a2f + + eyr:2029 ecl:blu cid:129 byr:1989 + iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm + + hcl:#888785 + hgt:164cm byr:2001 iyr:2015 cid:88 + pid:545766238 ecl:hzl + eyr:2022 + + iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719 + END + + for split-input($valid-data).kv -> $i, $passport { + ok data-validation($passport), "Run valid $i"; + } + + } + } +} |