mirror of
https://github.com/Crocmagnon/advent-of-code.git
synced 2024-11-24 15:38:10 +01:00
45 lines
1.5 KiB
Python
45 lines
1.5 KiB
Python
from collections import Counter
|
|
|
|
|
|
def main(filename: str, expected_part_1: int = None, expected_part_2: int = None):
|
|
counter_part_1 = 0
|
|
counter_part_2 = 0
|
|
with open(filename) as f:
|
|
for line in f:
|
|
if is_valid_part_1(*extract_password_and_policy(line)):
|
|
counter_part_1 += 1
|
|
if is_valid_part_2(*extract_password_and_policy(line)):
|
|
counter_part_2 += 1
|
|
|
|
print(f"Part1: Found {counter_part_1} valid passwords.")
|
|
print(f"Part2: Found {counter_part_2} valid passwords.")
|
|
if expected_part_1:
|
|
assert counter_part_1 == expected_part_1
|
|
if expected_part_2:
|
|
assert counter_part_2 == expected_part_2
|
|
|
|
|
|
def extract_password_and_policy(line) -> tuple[tuple[int, int], str, str]:
|
|
policy, password = line.strip().split(": ")
|
|
range_, letter = policy.split(" ")
|
|
range_ = range_.split("-")
|
|
range_ = int(range_[0]), int(range_[1])
|
|
return range_, letter, password
|
|
|
|
|
|
def is_valid_part_1(range_: tuple[int, int], letter: str, password: str):
|
|
counter = Counter(password)
|
|
return range_[0] <= counter[letter] <= range_[1]
|
|
|
|
|
|
def is_valid_part_2(range_: tuple[int, int], letter: str, password: str):
|
|
first_index = password[range_[0] - 1]
|
|
second_index = password[range_[1] - 1]
|
|
return first_index != second_index and (
|
|
first_index == letter or second_index == letter
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main("inputs/day02-tests", 2, 1)
|
|
main("inputs/day02")
|