Shorter solution with regex for 2020 day 04

This commit is contained in:
Akumatic
2020-12-04 18:30:54 +01:00
parent e424a1ebf3
commit 33f7c0100c
5 changed files with 1093 additions and 24 deletions

View File

@ -0,0 +1,37 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2020 Akumatic
#
# https://adventofcode.com/2020/day/4
import passport
def readFile() -> list:
with open(f"{__file__.rstrip('code.py')}input.txt", "r") as f:
return [line[:-1] for line in f.readlines()]
def parse_data(vals: list) -> list:
result = list()
cur = list()
for line in vals:
if line:
cur += line.split(" ")
else:
result.append(passport.Pass(cur))
cur.clear()
# since last line is not "", add data from cur once more
result.append(passport.Pass(cur))
return result
def part1(passports: list) -> int:
return sum(p.valid_fields() for p in passports)
def part2(passports: list) -> int:
return sum(p.valid_data() for p in passports)
if __name__ == "__main__":
from test_code import test
test()
passports = parse_data(readFile())
print(f"Part 1: {part1(passports)}")
print(f"Part 2: {part2(passports)}")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2020 Akumatic
class Pass:
def __init__(self, input):
tmp = dict()
for data in input:
d = data.split(":")
tmp[d[0]] = d[1]
self.byr = int(tmp["byr"]) if "byr" in tmp else None
self.iyr = int(tmp["iyr"]) if "iyr" in tmp else None
self.eyr = int(tmp["eyr"]) if "eyr" in tmp else None
self.hgt = tmp["hgt"] if "hgt" in tmp else None
self.hcl = tmp["hcl"] if "hcl" in tmp else None
self.ecl = tmp["ecl"] if "ecl" in tmp else None
self.pid = tmp["pid"] if "pid" in tmp else None
self.cid = tmp["cid"] if "cid" in tmp else None
def valid_fields(self) -> bool:
return all((self.byr, self.iyr, self.eyr, \
self.hgt, self.hcl, self.ecl, self.pid))
def valid_data(self):
if not self.valid_fields():
return False
return all((
validate_byr(self.byr),
validate_iyr(self.iyr),
validate_eyr(self.eyr),
validate_hgt(self.hgt),
validate_hcl(self.hcl),
validate_ecl(self.ecl),
validate_pid(self.pid)
))
def validate_byr(byr: int) -> bool:
return 1920 <= byr <= 2002
def validate_iyr(iyr: int) -> bool:
return 2010 <= iyr <= 2020
def validate_eyr(eyr: int) -> bool:
return 2020 <= eyr <= 2030
def validate_hgt(hgt: str) -> bool:
if not(hgt[-2:] in ("cm","in") and hgt[:-2].isnumeric()):
return False
i = int(hgt[:-2])
return 150 <= i <= 193 if hgt[-2:] == "cm" else 59 <= i <= 76
def validate_hcl(hcl: str) -> bool:
if not(len(hcl) == 7 and hcl[0] == "#"):
return False
return all(47 < ord(c) < 58 or 96 < ord(c) < 103 for c in hcl[1:])
def validate_ecl(ecl: str) -> bool:
return ecl in ("amb", "blu", "brn", "gry", "grn", "hzl", "oth")
def validate_pid(pid: str) -> bool:
return len(pid) == 9 and pid.isnumeric()

View File

@ -0,0 +1,42 @@
# SPDX-License-Identifier: MIT
# Copyright (c) 2020 Akumatic
from code import parse_data, part1
import passport
def test():
input = ["ecl:gry pid:860033327 eyr:2020 hcl:#fffffd","byr:1937 iyr:2017 cid:147 hgt:183cm",
"","iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884","hcl:#cfa07d byr:1929","",
"hcl:#ae17e1 iyr:2013","eyr:2024","ecl:brn pid:760753108 byr:1931", "hgt:179cm", "",
"hcl:#cfa07d eyr:2025 pid:166559648", "iyr:2011 ecl:brn hgt:59in"]
passports = parse_data(input)
assert len(passports) == 4
assert part1(passports) == 2
input = ["eyr:1972 cid:100","hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926","",
"iyr:2019","hcl:#602927 eyr:1967 hgt:170cm","ecl:grn pid:012533040 byr:1946","",
"hcl:dab227 iyr:2012","ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277","",
"hgt:59cm ecl:zzz","eyr:2038 hcl:74454a iyr:2023","pid:3556412378 byr:2007"]
passports = parse_data(input)
assert all((not p.valid_data() for p in passports))
input = ["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"]
passports = parse_data(input)
assert all((p.valid_data() for p in passports))
assert passport.validate_byr(2002) == True
assert passport.validate_byr(2003) == False
assert passport.validate_hgt("60in") == True
assert passport.validate_hgt("190cm") == True
assert passport.validate_hgt("190in") == False
assert passport.validate_hgt("190") == False
assert passport.validate_hcl("#123abc") == True
assert passport.validate_hcl("#123abz") == False
assert passport.validate_hcl("123abc") == False
assert passport.validate_ecl("brn") == True
assert passport.validate_ecl("wat") == False
assert passport.validate_pid("000000001") == True
assert passport.validate_pid("0123456789") == False