Posts

Advent of Code Day 4

Dec 4, 2020 | 5 minutes to read

Tags: geeky, software

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!


You can leave a comment on this post here.