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())
|