⛄ Day 4

Advent of Code is a coding challenge that releases a puzzle every day starting December 1st up until the 25th - like an Advent Calendar but no stale chocolate...

Part 1

Parse 'Passport Data' validating key value pairs for each passport is correct.
Solution:
                                
                                    
    import csv
    import time
    
    # byr (Birth Year)
    # iyr (Issue Year)
    # eyr (Expiration Year)
    # hgt (Height)
    # hcl (Hair Color)
    # ecl (Eye Color)
    # pid (Passport ID)
    # cid (Country ID)
    
    def get_passport_data(file_name):
        passport_data = []
        with open(file_name, 'r') as data:
            reader = csv.reader(data)
            data = []
            for line in reader:
                if len(line) != 0:
                    data.append(line[0])
                else:
                    passport_data.append(' '.join(data))
                    data = []
    
            passport_data.append(' '.join(data))
    
        return passport_data
    
    
    def parse_to_keys(data):
        d = {}
        for el in data.split(' '):
            [key, val] = el.split(':')
            d[key] = val
    
        return d
    
    
    def is_valid(d):
        keys = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid', 'cid']
        for key in keys:
            if key != 'cid' and d.get(key) is None:
                return False
    
        return True
        
                                
                            

Part 2

Parse 'Passport Data' but with more validation!
Solution:
                                
                                    
    # byr (Birth Year) - four digits; at least 1920 and at most 2002.
    # iyr (Issue Year) - four digits; at least 2010 and at most 2020.
    # eyr (Expiration Year) - four digits; at least 2020 and at most 2030.
    # hgt (Height) - a number followed by either cm or in:
    # If cm, the number must be at least 150 and at most 193.
    # If in, the number must be at least 59 and at most 76.
    # hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f.
    # ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth.
    # pid (Passport ID) - a nine-digit number, including leading zeroes.
    # cid (Country ID) - ignored, missing or not.
    
    # Note - this is probably the time for regex :P
    
    def valid_hgt(h):
        n = ''
        if h.find('cm') != -1:
            n = h.split('c')[0]
            try:
                num = int(n)
                return num >= 150 and num <= 193
            except:
                return False
        if h.find('in') != -1:
            n = h.split('i')[0]
            try:
                num = int(n)
                return num >= 59 and num <= 76
            except:
                return False
    
    
    valid_chars_hcl = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
    hcl_d = {}
    for v in valid_chars_hcl:
        hcl_d[v] = 'hello'
    
    def valid_hcl(h):
        chars = list(h)
        if len(h) != 7 and chars[0] != '#':
            return False
        for c in chars[1:]:
            if hcl_d.get(c) is None:
                return False
    
        return True
    
    
    ecl_keys = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']
    ecl_d = {}
    for v in ecl_keys:
        ecl_d[v] = 'hello'
    
    def valid_ecl(h):
        return ecl_d.get(h) is not None
    
    
    
    valid_chars_pid = ['0','1','2','3','4','5','6','7','8','9']
    pid_d = {}
    for v in valid_chars_pid:
        pid_d[v] = 'hello'
    
    
    def valid_pid(p):
        if len(p) != 9:
            return False
    
        for i in list(p):
            if pid_d.get(i) is None:
                return False
    
        return True
    
    
    pass_keys = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid', 'cid']
    
    def is_valid_2(d):
        for key in pass_keys:
            data = d.get(key)
            if key == 'byr' and data is not None:
                dt = int(data)
                if not (dt >= 1920 and dt <= 2002):
                    return False
            if key == 'iyr' and data is not None:
                dt = int(data)
                if not (dt >= 2010 and dt <= 2020):
                    return False
            if key == 'eyr' and data is not None:
                dt = int(data)
                if not (dt >= 2020 and dt <= 2030):
                    return False
            if key == 'hgt' and data is not None:
                is_valid_hgt = valid_hgt(data)
                if not is_valid_hgt:
                    return False
            if key == 'hcl' and data is not None:
                is_valid_hcl = valid_hcl(data)
                if not is_valid_hcl:
                    return False
            if key == 'ecl' and data is not None:
                is_valid_ecl = valid_ecl(data)
                if not is_valid_ecl:
                    return False
            if key == 'pid' and data is not None:
                is_valid_pid = valid_pid(data)
                if not is_valid_pid:
                    return False
            if key != 'cid' and d.get(key) is None:
                return False
    
        return True