Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from dataclasses import dataclass
- from typing import Generator
- @dataclass(slots=True, frozen=True)
- class IDRange:
- start: int
- stop: int
- def __iter__(self):
- """Handle creating the inclusive range"""
- for i in range(self.start, self.stop + 1):
- yield i
- def parse_data(filepath: str) -> list[IDRange]:
- ids = []
- with open(filepath, "r") as f:
- for line in f.readlines():
- for pair in line.split(","):
- l, r = map(int, pair.split("-"))
- ids.append(IDRange(l, r))
- return ids
- def all_duplicated(id: int) -> bool:
- """
- >>> assert all_duplicated(11) is True
- >>> assert all_duplicated(22) is True
- >>> assert all_duplicated(1010) is True
- >>> assert all_duplicated(1188511885) is True
- >>> assert all_duplicated(222222) is True
- >>> assert all_duplicated(446446) is True
- >>> assert all_duplicated(38593859) is True
- >>> assert all_duplicated(12) is False
- >>> assert all_duplicated(999) is False
- >>> assert all_duplicated(9999) is True
- """
- id_str = str(id)
- if len(id_str) % 2 != 0:
- return False
- half = len(id_str) // 2
- if id_str[0:half] == id_str[half : len(id_str)]:
- return True
- return False
- def any_duplicated(id: int) -> bool:
- """
- >>> assert any_duplicated(12341234) is True
- >>> assert any_duplicated(123123123) is True
- >>> assert any_duplicated(1212121212) is True
- >>> assert any_duplicated(2121212118) is False
- >>> assert any_duplicated(2121212119) is False
- >>> assert any_duplicated(2121212121) is True
- """
- id_str = str(id)
- id_length = len(id_str)
- for size in range(1, (id_length // 2) + 1):
- segments, r = divmod(id_length, size)
- if r != 0:
- continue
- splits = [
- id_str[size * segment : size * segment + size]
- for segment in range(segments)
- ]
- if all(splits[0] == splits[i] for i in range(len(splits))):
- return True
- return False
- def invalid_from_range(
- id_range: IDRange, dup_func=all_duplicated
- ) -> Generator[int, None, None]:
- """
- >>> id_range = IDRange(11, 22)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [11, 22]
- >>> id_range = IDRange(95, 115)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [99, 111]
- >>> id_range = IDRange(998, 1012)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [999, 1010]
- >>> id_range = IDRange(1188511880, 1188511890)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [1188511885]
- >>> id_range = IDRange(222220, 222224)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [222222]
- >>> id_range = IDRange(1698522, 1698528)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == []
- >>> id_range = IDRange(446443, 446449)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [446446]
- >>> id_range = IDRange(38593856,38593862)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [38593859]
- >>> id_range = IDRange(565653, 565659)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [565656]
- >>> id_range = IDRange(824824821,824824827)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [824824824]
- >>> id_range = IDRange(2121212118,2121212124)
- >>> assert [*invalid_from_range(id_range, any_duplicated)] == [2121212121]
- """
- for i in id_range:
- if dup_func(i):
- yield i
- def calculate_total_invalid_ids(ids: list[IDRange], dup_func=all_duplicated) -> int:
- invalid_id_total = 0
- for id_range in ids:
- for id in id_range:
- if dup_func(id):
- invalid_id_total += id
- return invalid_id_total
- def part_a():
- fp = "day02.txt"
- id_ranges = parse_data(fp)
- total = calculate_total_invalid_ids(id_ranges)
- print(total)
- def part_b():
- fp = "day02.txt"
- id_ranges = parse_data(fp)
- total = calculate_total_invalid_ids(id_ranges, any_duplicated)
- print(total)
- if __name__ == "__main__":
- part_a()
- part_b()
Add Comment
Please, Sign In to add comment