/
day04
executable file
·68 lines (54 loc) · 2.03 KB
/
day04
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/python
# Floris Douw
# 2020
#
# AoC 2020 Day 4: Passport Processing
import re
keyval_pat = re.compile(r'([a-z]{3}):(\S+)')
colour_pat = re.compile(r'#[0-9a-fA-F]{6}')
passid_pat = re.compile(r'\d{9}')
def extract_pass(data):
return {k: v for k, v in keyval_pat.findall(data)}
def validate_intrange(txt, min, max):
return txt.isdigit() and int(txt) >= min and int(txt) <= max
def validate_passdata(data):
if 'byr' not in data or not validate_intrange(data['byr'], 1920, 2002):
return False
if 'iyr' not in data or not validate_intrange(data['iyr'], 2010, 2020):
return False
if 'eyr' not in data or not validate_intrange(data['eyr'], 2020, 2030):
return False
if 'hgt' not in data:
return False
elif data['hgt'].endswith('cm'):
if not validate_intrange(data['hgt'][:-2], 150, 193):
return False
elif data['hgt'].endswith('in'):
if not validate_intrange(data['hgt'][:-2], 59, 76):
return False
else: # suffix wrong (neither cm nor in)
return False
if 'hcl' not in data or not colour_pat.fullmatch(data['hcl']):
return False
if 'ecl' not in data or data['ecl'] not in ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']:
return False
if 'pid' not in data or not passid_pat.fullmatch(data['pid']):
return False
return keyref.issuperset(data.keys())
with open('input/day04', 'r') as f:
passportdata = re.split(r'\n\s*\n', f.read().strip())
keyref = set(['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid', 'cid'])
# Part 1
count = 0
for entry in passportdata:
passport = set([d.split(':')[0] for d in re.split(r'\s+', entry)])
if passport.issubset(keyref):
if passport.issuperset(keyref):
count += 1
elif passport.symmetric_difference(keyref).issubset(['cid']):
count += 1
print(f'Part 1: {count}')
# Part 2
passports = [extract_pass(entry) for entry in passportdata]
count = sum(1 for data in passports if validate_passdata(data))
print(f'Part 2: {count}')