--- /dev/null
+#!/usr/bin/python3
+
+REQUIRED_FIELDS=(('byr', "Birth Year"),('iyr', "Issue Year"),('eyr', "Expiration Year"),('hgt', "Height"),('hcl', "Hair Colour"),('ecl', "Eye Colour"),('pid',"Passport ID"))
+OPTIONAL_FIELDS=(('cid', "Country ID"))
+VALID_EYE_COLOURS=('amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth')
+
+def check_passport(passport_data):
+ print(passport_data)
+ for field in REQUIRED_FIELDS:
+ if field[0] not in passport_data:
+ return False
+ # check the field data
+ if field[0] == 'byr':
+ if not check_year(passport_data[field[0]], 1920, 2002):
+ return False
+ elif field[0] == 'iyr':
+ if not check_year(passport_data[field[0]], 2010, 2020):
+ return False
+ elif field[0] == 'eyr':
+ if not check_year(passport_data[field[0]], 2020, 2030):
+ return False
+ elif field[0] == 'hgt':
+ if not check_height(passport_data[field[0]]):
+ return False
+ elif field[0] == 'hcl':
+ if not check_hair_colour(passport_data[field[0]]):
+ return False
+ elif field[0] == 'ecl':
+ if not passport_data[field[0]] in VALID_EYE_COLOURS:
+ return False
+ elif field[0] == 'pid':
+ if not check_pid(passport_data[field[0]]):
+ return False
+ return True
+
+def check_year(data, min_year, max_year):
+ try:
+ year = int(data)
+ if year >= min_year and year <= max_year:
+ return True
+ return False
+ except:
+ return False
+
+def check_height(data):
+ try:
+ unit = data[-2:]
+ value = int(data[:-2])
+
+ if unit == "cm":
+ if value >= 150 and value <= 193:
+ return True
+ elif unit == "in":
+ if value >= 59 and value <= 76:
+ return True
+ return False
+ except:
+ return False
+
+def check_hair_colour(data):
+ if data[0] != "#":
+ return False
+ if len(data) != 7:
+ return False
+ if data != data.lower():
+ return False
+ try:
+ value = int(data[1:], 16)
+ return True
+ except:
+ return False
+ return False
+
+def check_pid(data):
+ # first check that the string length is correct
+ if len(data) != 9:
+ return False
+
+ # now check that it's a number
+ try:
+ int(data, 10)
+ return True
+ except:
+ return False
+
+def main():
+ new_passport=False
+ passport_data=dict()
+ valid_passports=0
+ for line in open("input.txt"):
+ if new_passport:
+ if check_passport(passport_data):
+ valid_passports += 1
+ passport_data.clear()
+ line=line.rstrip()
+ if line == '':
+ new_passport=True
+ continue
+ new_passport=False
+ parts=line.split(" ")
+ for part in parts:
+ (key, value) = part.split(":")
+ passport_data[key] = value
+ if not new_passport:
+ if check_passport(passport_data):
+ valid_passports += 1
+ print("Found", valid_passports, "valid passports")
+
+main()