summaryrefslogtreecommitdiffstats
path: root/day4/__init__.py
blob: d52d0a15309a6e0375829b695b21f9f5a3e0961a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# -*- coding: utf-8 -*-
from abc import ABC
from typing import Iterator

from aoc import BaseAssignment, I, T
from aoc.datastructures import Coordinate


class Assignment(BaseAssignment, ABC):
    def parse_item(cls, item: str) -> Iterator[list[str]]:
        yield [c for c in item]

    @classmethod
    def check_accessible_coordinate(
        cls, field: list[list[str]], coordinate: Coordinate
    ) -> bool:
        neighbouring_roll_count = 0
        for neighbor in coordinate.neighbours():
            if neighbor.in_bounds(field) and field[neighbor.y][neighbor.x] == "@":
                neighbouring_roll_count += 1

        return neighbouring_roll_count < 4

    @classmethod
    def get_accessible_coordinates(
        cls, field: list[list[str]], coordinates: list[Coordinate]
    ) -> list[Coordinate]:
        accessible_coordinates = []
        for coordinate in coordinates:
            if field[coordinate.y][coordinate.x] != "@":
                continue

            if cls.check_accessible_coordinate(field, coordinate):
                accessible_coordinates.append(coordinate)

        return accessible_coordinates


class AssignmentOne(Assignment):
    example_result = 13

    def run(self, input: Iterator[str]) -> int:
        field = [next(self.parse_item(i)) for i in input]

        coordinates = [
            Coordinate(x, y) for y in range(len(field)) for x in range(len(field[y]))
        ]

        return len(self.get_accessible_coordinates(field, coordinates))


class AssignmentTwo(Assignment):
    example_result = 43

    def run(self, input: Iterator[str]) -> int:
        field = [next(self.parse_item(i)) for i in input]

        coordinates = [
            Coordinate(x, y) for y in range(len(field)) for x in range(len(field[y]))
        ]

        rolls_removed = 0
        while True:
            accessible_coordinates = self.get_accessible_coordinates(field, coordinates)

            if len(accessible_coordinates) == 0:
                return rolls_removed

            for coordinate in accessible_coordinates:
                field[coordinate.y][coordinate.x] = "."

            rolls_removed += len(accessible_coordinates)