aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Brattlof <hello@bryanbrattlof.com>2020-12-13 14:54:38 -0500
committerBryan Brattlof <hello@bryanbrattlof.com>2020-12-13 14:54:38 -0500
commit2755dd89427c9a35687b9ff392696ea770fadfb8 (patch)
treebde5cdc851541380b122fd5e1c3e354008753a43
parent9f6c65c6ae5214812d0bd527aed948dd426324a4 (diff)
downloadadvent-of-code-2755dd89427c9a35687b9ff392696ea770fadfb8.tar.gz
advent-of-code-2755dd89427c9a35687b9ff392696ea770fadfb8.tar.bz2
day 4.2 of Advent of Code 2020
-rw-r--r--2020/day04/passport-processing.py68
-rw-r--r--2020/day04/readme.rst99
2 files changed, 163 insertions, 4 deletions
diff --git a/2020/day04/passport-processing.py b/2020/day04/passport-processing.py
index d30884b..49b7196 100644
--- a/2020/day04/passport-processing.py
+++ b/2020/day04/passport-processing.py
@@ -1,4 +1,5 @@
from typing import Dict, List, Generator
+import re
EXAMPLE = """ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
byr:1937 iyr:2017 cid:147 hgt:183cm
@@ -34,3 +35,70 @@ assert sum((is_valid(p) for p in parse_passports(EXAMPLE))) == 2
with open('data/passports.txt') as f:
print(f'valid: {sum((is_valid(p) for p in parse_passports(f.read())))}')
+
+# Part 2
+
+INVALID = """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"""
+
+VALID = """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"""
+
+# You can continue to ignore the cid field, but each other field has strict
+# rules about what values are valid for automatic validation:
+
+# byr (Birth Year) - four digits; at least 1920 and at most 2002.
+# iyr (Issue Year) - four digits; at least 2010 and at most 2020.
+# eyr (Expiration Year) - four digits; at least 2020 and at most 2030.
+# hgt (Height) - a number followed by either cm or in:
+# If cm, the number must be at least 150 and at most 193.
+# If in, the number must be at least 59 and at most 76.
+# hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f.
+# ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth.
+# pid (Passport ID) - a nine-digit number, including leading zeroes.
+# cid (Country ID) - ignored, missing or not.
+
+def is_valid_height(height: str) -> bool:
+ if height.endswith('cm'):
+ return 150 <= int(height[:-2]) <= 193
+ if height.endswith('in'):
+ return 59 <= int(height[:-2]) <= 76
+ return False
+
+def is_valid2(passport: Passport) -> bool:
+ """is the criteria valid"""
+ return all([
+ 1920 <= int(passport.get('byr', -1)) <= 2002,
+ 2010 <= int(passport.get('iyr', -1)) <= 2020,
+ 2020 <= int(passport.get('eyr', -1)) <= 2030,
+ is_valid_height(passport.get('hgt', '')),
+ re.match(r'^#[0-9a-f]{6}$', passport.get('hcl', '')),
+ passport.get('ecl', '') in ['amb', 'blu', 'brn','gry','grn','hzl','oth'],
+ re.match(r'^[0-9]{9}$', passport.get('pid', '0'))])
+
+assert not all(is_valid2(p) for p in parse_passports(INVALID))
+assert all(is_valid2(p) for p in parse_passports(VALID))
+
+with open('data/passports.txt') as f:
+ print(f'valid2: {sum((is_valid2(p) for p in parse_passports(f.read())))}')
diff --git a/2020/day04/readme.rst b/2020/day04/readme.rst
index 4ecdcfc..5dc89da 100644
--- a/2020/day04/readme.rst
+++ b/2020/day04/readme.rst
@@ -20,10 +20,10 @@ which passports have all required fields. The expected fields are as follows:
- iyr (Issue Year)
- eyr (Expiration Year)
- hgt (Height)
-- hcl (Hair Color)
-- ecl (Eye Color)
-- pid (Passport ID)
-- cid (Country ID)
+- hcl (Hair Color)
+- ecl (Eye Color)
+- pid (Passport ID)
+- cid (Country ID)
Passport data is validated in batch files (your puzzle input). Each passport is
represented as a sequence of key:value pairs separated by spaces or newlines.
@@ -63,3 +63,94 @@ passports.
Count the number of valid passports - those that have all required fields. Treat
cid as optional. In your batch file, how many passports are valid?
+
+Your puzzle answer was 192.
+
+The first half of this puzzle is complete! It provides one gold star: *
+
+Part Two
+########
+
+The line is moving more quickly now, but you overhear airport security talking
+about how passports with invalid data are getting through. Better add some data
+validation, quick!
+
+You can continue to ignore the cid field, but each other field has strict rules
+about what values are valid for automatic validation:
+
+- byr (Birth Year) - four digits; at least 1920 and at most 2002.
+- iyr (Issue Year) - four digits; at least 2010 and at most 2020.
+- eyr (Expiration Year) - four digits; at least 2020 and at most 2030.
+- hgt (Height) - a number followed by either cm or in:
+ - If cm, the number must be at least 150 and at most 193.
+ - If in, the number must be at least 59 and at most 76.
+- hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f.
+- ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth.
+- pid (Passport ID) - a nine-digit number, including leading zeroes.
+- cid (Country ID) - ignored, missing or not.
+
+Your job is to count the passports where all required fields are both present
+and valid according to the above rules. Here are some example values:
+
+.. code-block::
+
+ byr valid: 2002
+ byr invalid: 2003
+
+ hgt valid: 60in
+ hgt valid: 190cm
+ hgt invalid: 190in
+ hgt invalid: 190
+
+ hcl valid: #123abc
+ hcl invalid: #123abz
+ hcl invalid: 123abc
+
+ ecl valid: brn
+ ecl invalid: wat
+
+ pid valid: 000000001
+ pid invalid: 0123456789
+
+Here are some invalid passports:
+
+.. code-block::
+
+ 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
+
+Here are some valid passports:
+
+.. code-block::
+
+ 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
+
+Count the number of valid passports - those that have all required fields and
+valid values. Continue to treat cid as optional. In your batch file, how many
+passports are valid?
+
+Your puzzle answer was 101.
+
+Both parts of this puzzle are complete! They provide two gold stars: **