<jupyter_start><jupyter_text>Day 04Let's get the data first.<jupyter_code>import aocd, json, re
passports = aocd.get_data(day=4, year=2020).split('\n\n')

# passports = """pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980
# hcl:#623a2f

# eyr:2029 ecl:blu cid:129 byr:1989
# iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm

# hcl:#888785
# hgt:164cm byr:2001 iyr:2015 cid:88
# pid:545766238 ecl:hzl
# eyr:2022

# iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719""".split('\n\n')

for i, passport in enumerate(passports):
    passport = '{\"' + passport.replace('\n', ' ').replace(' ', '", "').replace(':', '":"') + '\"}'
    passport = json.loads(passport)
    passports[i] = passport

# print(passports)<jupyter_output><empty_output><jupyter_text>Part 1<jupyter_code>req_fields = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid']
invalid = 0

for passport in passports:
    for field in req_fields:
        if not field in passport:
            invalid += 1
            break

print(len(passports) - invalid)<jupyter_output>247<jupyter_text>Part 2<jupyter_code>def validate(field, value):
    if field == 'byr':
        return int(value) >= 1920 and int(value) <= 2002
    elif field == 'iyr':
        return int(value) >= 2010 and int(value) <= 2020
    elif field == 'eyr':
        return int(value) >= 2020 and int(value) <= 2030
    elif field == 'hgt':
        if value[-2:] == 'cm':
            return int(value[:-2]) >= 150 and int(value[:-2]) <= 193
        elif value[-2:] == 'in':
            return int(value[:-2]) >= 59 and int(value[:-2]) <= 76
        else:
            return False
    elif field == 'hcl':
        return bool(len(re.findall('^#[0-9a-f]{6}$', value)))
    elif field == 'ecl':
        return value in ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth']
    elif field == 'pid':
        return bool(len(re.findall('^[0-9]{9}$', value)))
    elif field == 'cid':
        return True
    else:
        return False

# tests = [{'byr': '2002'}, {'byr': '2003'}, {'hgt': '60in'}, {'hgt': '190cm'}, {'hgt': '190in'}, {'hgt': '190'}, {'hcl': '#123abc'}, {'hcl': '#123abz'}, {'hcl': '123abc'}, {'ecl': 'brn'}, {'ecl': 'wat'}, {'pid': '000000001'}, {'pid': '0123456789'}]

# for test in tests:
#     for field, value in test.items() :
#         print(field, validate(field, value), value)

req_fields = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid']
invalid = 0

for passport in passports:
    passport_valid = True
    # print(passport)
    for field in req_fields:
        if not field in passport:
            passport_valid = False
    # print('req_fields', passport_valid)
    for field, value in passport.items() :
        # print(field, validate(field, value), value)
        if not validate(field, value):
            passport_valid = False
    if passport_valid == False:
        invalid += 1

print(len(passports) - invalid)<jupyter_output>145
{'fraction_non_alphanumeric': 0.19242685025817555, 'fraction_numerical': 0.07951807228915662, 'mean_word_length': 3.324404761904762, 'pattern_counts': {'":': 1, '<': 16, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '602559', 'license': 'MIT', 'n_tokens_mistral': 1252, 'n_tokens_neox': 1071, 'n_words': 264, 'path': '2020/Day04.ipynb', 'repo_name': 'jamesturton/advent_of_code', 'size': '2905'}