53 lines
1.1 KiB
Python
53 lines
1.1 KiB
Python
import sys
|
|
import typing
|
|
|
|
|
|
def main() -> int:
|
|
checked = [passport.is_valid() for passport in _read_passports(sys.stdin)]
|
|
print(f"total={len(checked)} valid={checked.count(True)}")
|
|
return 0
|
|
|
|
|
|
NoneString = typing.Optional[str]
|
|
|
|
|
|
class Passport:
|
|
byr: NoneString = None
|
|
cid: NoneString = None
|
|
ecl: NoneString = None
|
|
eyr: NoneString = None
|
|
hcl: NoneString = None
|
|
hgt: NoneString = None
|
|
iyr: NoneString = None
|
|
pid: NoneString = None
|
|
|
|
def is_valid(self) -> bool:
|
|
return all(
|
|
[
|
|
getattr(self, attr) is not None
|
|
for attr in ("byr", "ecl", "eyr", "hcl", "hgt", "iyr", "pid")
|
|
]
|
|
)
|
|
|
|
|
|
def _read_passports(
|
|
instream: typing.BinaryIO,
|
|
) -> typing.Generator[None, None, Passport]:
|
|
cur = Passport()
|
|
|
|
for i, line in enumerate(instream):
|
|
line = line.strip()
|
|
if line == "":
|
|
yield cur
|
|
cur = Passport()
|
|
|
|
for pair in line.split():
|
|
attr, value = pair.split(":", 1)
|
|
setattr(cur, attr, value)
|
|
|
|
yield cur
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|