Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from copy import deepcopy
- from dataclasses import dataclass
- from typing import Iterable
- @dataclass(slots=True, frozen=True)
- class Floor:
- paper_locations: frozenset[complex]
- def parse_data(fp: str) -> Floor:
- paper_locations = set()
- with open(fp, "r") as f:
- for y, line in enumerate(map(str.strip, f.readlines())):
- for x, v in enumerate(line):
- x_max = x
- y_max = y
- if v == "@":
- paper_locations.add(complex(x, y))
- return Floor(paper_locations=frozenset(paper_locations))
- DIRECTIONS = (
- complex(-1, 1),
- complex(0, 1),
- complex(1, 1),
- complex(-1, 0),
- complex(1, 0),
- complex(-1, -1),
- complex(0, -1),
- complex(1, -1),
- )
- def count_adjacent(
- position: complex, floor: Floor, directions: Iterable[complex] = DIRECTIONS
- ) -> int:
- return sum(
- direction + position in floor.paper_locations for direction in directions
- )
- def iter_find_accessible_paper_locations(floor: Floor) -> Iterable[complex]:
- for position in floor.paper_locations:
- if count_adjacent(position, floor) < 4:
- yield position
- def find_removable_roll_count(floor: Floor) -> int:
- initial_floor = deepcopy(floor)
- current_floor = deepcopy(floor)
- while True:
- removable = set(iter_find_accessible_paper_locations(current_floor))
- next_floor = Floor(frozenset(current_floor.paper_locations - removable))
- if current_floor == next_floor:
- return len(initial_floor.paper_locations - current_floor.paper_locations)
- current_floor = next_floor
- def part_a() -> None:
- """
- >>> fp = "day04a.txt"
- >>> floor = parse_data(fp)
- >>> assert len([*iter_find_accessible_paper_locations(floor)]) == 13
- """
- fp = "day04.txt"
- floor = parse_data(fp)
- accessible_paper_locations_count = len(
- [*iter_find_accessible_paper_locations(floor)]
- )
- print(accessible_paper_locations_count)
- def part_b():
- """
- >>> fp = "day04a.txt"
- >>> floor = parse_data(fp)
- >>> assert find_removable_roll_count(floor) == 43
- """
- fp = "day04.txt"
- floor = parse_data(fp)
- removable_count = find_removable_roll_count(floor)
- print(removable_count)
- if __name__ == "__main__":
- part_a()
- part_b()
Add Comment
Please, Sign In to add comment