aoc2020/day04.py
Stefan Harmuth a70f2daf7f day 4
2020-12-04 07:06:51 +01:00

98 lines
2.5 KiB
Python

#!/usr/bin/env python3
import aoclib
import re
DAY = 4
required_fields = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid'] # 'cid' possible, but ignored
re_color_match = re.compile(r'#[a-z0-9]{6}')
def getPassportData(passport_line):
data = {}
pairs = passport_line.split()
for pair in pairs:
key, value = pair.split(':')
data[key] = value
return data
def verifyPassportData(passport_data, verify_data=False):
for field in required_fields:
if field not in passport_data:
return False
if not verify_data:
return True
try:
birth_year = int(passport_data['byr'])
issue_year = int(passport_data['iyr'])
expire_year = int(passport_data['eyr'])
height = int(passport_data['hgt'][:-2])
int(passport_data['pid'])
except ValueError:
return False
# BYR
if len(passport_data['byr']) != 4 or birth_year < 1920 or birth_year > 2002:
return False
# IYR
if len(passport_data['iyr']) != 4 or issue_year < 2010 or issue_year > 2020:
return False
# EYR
if len(passport_data['eyr']) != 4 or expire_year < 2020 or expire_year > 2030:
return False
# HGT
if passport_data['hgt'][-2:] not in ['cm', 'in']:
return False
elif passport_data['hgt'].endswith('cm') and (height < 150 or height > 193):
return False
elif passport_data['hgt'].endswith('in') and (height < 59 or height > 76):
return False
# HCL
if not re.match(re_color_match, passport_data['hcl']):
return False
# ECL
if passport_data['ecl'] not in ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']:
return False
# PID
if len(passport_data['pid']) != 9:
return False
return True
def part1(test_mode=False):
valid = 0
for passport_line in aoclib.getMultiLineInputAsArray(day=4, test=test_mode):
passport_data = getPassportData(passport_line)
if verifyPassportData(passport_data):
valid = valid + 1
return valid
def part2(test_mode=False):
valid = 0
for passport_line in aoclib.getMultiLineInputAsArray(day=4, test=test_mode):
passport_data = getPassportData(passport_line)
if verifyPassportData(passport_data, True):
valid = valid + 1
return valid
if __name__ == '__main__':
assert part1(test_mode=True) == 10, "Part 1 TEST FAILED"
aoclib.printSolution(DAY, 1, part1())
assert part2(test_mode=True) == 6, "Part 2 TEST FAILED"
aoclib.printSolution(DAY, 2, part2())