main About me Back to Posts Personal Projects Links Privacy Contact
Whew! This is getting tricky! (See my earlier post for a quick explanation on what Advent of Code is)
Today’s puzzle had us parsing a long text file with paswsport attributes spread out over many lines. The first part just asked the code to count the number of valid attributes for each passport (7 or 8 are OK) but the second part had specific validations for each and those were a brea to get exactly right (for me).
Code for Part 1:
# Advent of Code 2020 Day 4 - In your batch file, how many passports are valid?
# byr (Birth Year)
# iyr (Issue Year)
# eyr (Expiration Year)
# hgt (Height)
# hcl (Hair Color)
# ecl (Eye Color)
# pid (Passport ID)
# cid (Country ID)
log = ""
class aPassport:
def __init__(self):
self.byr = False
self.iyr = False
self.eyr = False
self.hgt = False
self.hcl = False
self.ecl = False
self.pid = False
self.cid = True
def update(self, arrUpdate):
for entry in arrUpdate:
# print(str(entry[0:3]))
if entry[0:3] == 'byr':
self.byr = True
if entry[0:3] == 'iyr':
self.iyr = True
if entry[0:3] == 'eyr':
self.eyr = True
if entry[0:3] == 'hgt':
self.hgt = True
if entry[0:3] == 'hcl':
self.hcl = True
if entry[0:3] == 'ecl':
self.ecl = True
if entry[0:3] == 'pid':
self.pid = True
return
def allFieldsValid(self):
if self.byr != False:
if self.iyr != False:
if self.eyr != False:
if self.hgt != False:
if self.hcl != False:
if self.ecl != False:
if self.pid != False:
return True
return False
def addToLog(value):
global log
log += value + "\n"
lastline = 1069
validPassportCount = 0
passportCount = 1
thisPassport = aPassport()
with open("c:\\git\\advent-2020\\4.txt", "r") as f:
passlist = f.read().splitlines()
f.close()
# print(passlist)
for aPass in passlist:
if aPass == "":
if thisPassport.allFieldsValid():
validPassportCount += 1
addToLog("valid!!! " + str(validPassportCount ) + ' ' + str(passportCount))
addToLog(' ')
del thisPassport
passportCount += 1
continue
addToLog(aPass)
passArray = aPass.split(' ')
try:
thisPassport.update(passArray)
except:
thisPassport = aPassport()
thisPassport.update(passArray)
if lastline == 1:
if thisPassport.allFieldsValid():
validPassportCount += 1
addToLog("valid!!! " + str(validPassportCount ) + ' ' + str(passportCount))
lastline -= 1
addToLog('There are ' + str(validPassportCount) + ' valid passports, out of ' + str(passportCount) + ' total in this file')
fl = open("4-1-log.txt", "w")
fl.write(log)
fl.close()
print('There are ' + str(validPassportCount) + ' valid passports, out of ' + str(passportCount) + ' total in this file')
Code for Part 2:
# Advent of Code 2020 Day 4 - In your batch file, how many passports are valid?
# byr (Birth Year)
# iyr (Issue Year)
# eyr (Expiration Year)
# hgt (Height)
# hcl (Hair Color)
# ecl (Eye Color)
# pid (Passport ID)
# cid (Country ID)
import re
log = ""
class aPassport:
def __init__(self):
self.byr = False
self.iyr = False
self.eyr = False
self.hgt = False
self.hcl = False
self.ecl = False
self.pid = False
self.cid = True
def update(self, arrUpdate):
for entry in arrUpdate:
if entry[0:3] == 'byr' and self.isValidBYR(entry):
self.byr = True
if entry[0:3] == 'iyr' and self.isValidIYR(entry):
self.iyr = True
if entry[0:3] == 'eyr' and self.isValidEYR(entry):
self.eyr = True
if entry[0:3] == 'hgt' and self.isValidHGT(entry):
self.hgt = True
if entry[0:3] == 'hcl' and self.isValidHCL(entry):
self.hcl = True
if entry[0:3] == 'ecl' and self.isValidECL(entry):
self.ecl = True
if entry[0:3] == 'pid' and self.isValidPID(entry):
self.pid = True
return
def isValidBYR(self, entry):
try:
val = int(entry[4:])
except:
return False
if val >= 1920 and val <= 2002:
return True
return False
def isValidIYR(self, entry):
try:
val = int(entry[4:])
except:
return False
if val >= 2010 and val <= 2020:
return True
return False
def isValidEYR(self, entry):
try:
val = int(entry[4:])
except:
return False
if val >= 2020 and val <= 2030:
return True
return False
def isValidHGT(self, entry):
try:
val = entry[4:]
unit = val[-2:]
if unit == 'cm':
val = val[:val.find('c')]
if int(val) >= 150 and int(val) <= 193:
return True
if unit == 'in':
val = val[:val.find('i')]
if int(val) >= 59 and int(val) <= 76:
return True
return False
except:
return False
def isValidHCL(self, entry):
val = entry[4:]
if (val[0:1] == '#'):
res = re.search("[a-f0-9]{6,}", val[1:])
if type(res) == re.Match:
return True
return False
def isValidECL(self, entry):
val = entry[4:]
if val == 'amb' or val == 'blu' or val == 'brn' or val == 'gry' or val == 'grn' or val == 'hzl' or val == 'oth':
return True
return False
def isValidPID(self, entry):
val = entry[4:]
if len(val) == 9:
try:
ival = int(val)
return True
except:
return False
return False
def allFieldsValid(self):
if self.byr != False:
if self.iyr != False:
if self.eyr != False:
if self.hgt != False:
if self.hcl != False:
if self.ecl != False:
if self.pid != False:
return True
return False
def addToLog(value):
global log
log += value + "\n"
lastline = 1069
validPassportCount = 0
passportCount = 1
thisPassport = aPassport()
with open("c:\\git\\advent-2020\\4.txt", "r") as f:
passlist = f.read().splitlines()
f.close()
# print(passlist)
for aPass in passlist:
if aPass == "":
if thisPassport.allFieldsValid():
validPassportCount += 1
addToLog("valid!!! " + str(validPassportCount ) + ' ' + str(passportCount))
addToLog(' ')
del thisPassport
passportCount += 1
continue
addToLog(aPass)
passArray = aPass.split(' ')
try:
thisPassport.update(passArray)
except:
thisPassport = aPassport()
thisPassport.update(passArray)
if lastline == 1:
if thisPassport.allFieldsValid():
validPassportCount += 1
addToLog("valid!!! " + str(validPassportCount ) + ' ' + str(passportCount))
lastline -= 1
addToLog('There are ' + str(validPassportCount) + ' valid passports, out of ' + str(passportCount) + ' total in this file')
fl = open("4-2-log.txt", "w")
fl.write(log)
fl.close()
print('There are ' + str(validPassportCount) + ' valid passports, out of ' + str(passportCount) + ' total in this file')
Cheers!