summary refs log tree commit diff stats
path: root/2020/day-04/day-04.raku
blob: e7bb0b938c5a4ae6a5df934aec7aa4079be3e011 (plain) (blame)
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
#!/usr/bin/env raku

sub MAIN (
    # Part to run.
    Int $part where * == 1|2 = 1
) {
    my $input = slurp "input";
    my @passports = $input.split("\n\n");
    my $valid_passports = 0;

    MAIN: for @passports -> $passport {
        my %fields;

        for $passport.words -> $field {
            my ($key, $value) = $field.split(":");
            %fields{$key} = $value;
        }

        # Check for fields that are strictly required. `cid' can
        # be skipped. Skip this passport if it's not valid.
        for <byr iyr eyr hgt hcl ecl pid> -> $field {
            next MAIN unless %fields{$field};
        }

        # Do validation in part 2.
        if $part == 2 {
            next MAIN unless (
                (1920%fields{<byr>} ≤ 2002)
                and (2010%fields{<iyr>} ≤ 2020)
                and (2020%fields{<eyr>} ≤ 2030)
                and (<amb blu brn gry grn hzl oth>%fields{<ecl>})
                and (%fields{<pid>} ~~ /^\d ** 9$/)
                and (%fields{<hcl>} ~~ /^'#' <[\d a..f]> ** 6/)
            );
            given substr(%fields{<hgt>}, *-2) {
                when 'cm' {
                    next MAIN unless 150substr(%fields{<hgt>}, 0, *-2) ≤ 193;
                }
		when 'in' {
                    next MAIN unless 59substr(%fields{<hgt>}, 0, *-2) ≤ 76;
                }
                default { next MAIN; }
	    }
        }
        $valid_passports++;
    }
    say "Part $part: " ~ $valid_passports;
}