aoc/2020/04/04.py

94 lines
2.3 KiB
Python
Raw Normal View History

2020-12-04 08:59:23 +00:00
def read_file():
with open("input.txt","r") as f:
# first, we split into separate passports.
raw_passports = f.read().split('\n\n')
# then, we split each passport into fields, by newline or space.
split_passports = []
for passport in raw_passports:
split_passports.append(passport.split())
# finally, we convert to a dictionary.
passports = []
for passport in split_passports:
passport_dict = {}
for field in passport:
key, value = field.split(':')
passport_dict[key] = value
passports.append(passport_dict)
# all passports should now be normalized to dicts.
return passports
def valid(passport):
required_fields = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid']
for field in required_fields:
if field not in passport:
return False
return True
def part1(passports):
valid_passports = 0
for passport in passports:
if valid(passport):
valid_passports += 1
return valid_passports
def valid_data(passport):
# first, we need to check if all required fields are present.
if not valid(passport):
return False
# byr must be four digits 1920 - 2002
byr = int(passport['byr'])
if not (1920 <= byr <= 2002):
return False
# iyr must be four digits 2010 - 2020
iyr = int(passport['iyr'])
if not (2010 <= iyr <= 2020):
return False
#eyr must be four digits 2020 - 2030
eyr = int(passport['eyr'])
if not (2020 <= eyr <= 2030):
return False
# hgt must be 150-193cm or 59-76in
hgt = passport['hgt']
if hgt.endswith('cm'):
hgt = int(hgt[:-2])
if not (150 <= hgt <= 193):
return False
elif hgt.endswith('in'):
hgt = int(hgt[:-2])
if not (59 <= hgt <= 76):
return False
else:
return False
# hcl must be hexcode
hcl = passport['hcl']
import re
if not re.match(r'^#(?:[0-9a-fA-F]{1,2}){3}$', hcl):
return False
# ecl must be exactly one of: amb blu brn gry grn hzl oth.
valid_ecls = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']
ecl = passport['ecl']
if ecl not in valid_ecls:
return False
# pid must be 9 digits long
pid = passport['pid']
if len(pid) != 9:
return False
# cid is ignored
return True
def part2(passports):
valid_passports = 0
for passport in passports:
if valid_data(passport):
valid_passports += 1
return valid_passports
def main():
passports = read_file()
print(f'{part1(passports)=}')
print(f'{part2(passports)=}')
if __name__ == "__main__":
main()