diff options
Diffstat (limited to 'day9/__init__.py')
| -rw-r--r-- | day9/__init__.py | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/day9/__init__.py b/day9/__init__.py index f198deb..4846468 100644 --- a/day9/__init__.py +++ b/day9/__init__.py | |||
| @@ -34,6 +34,8 @@ class Coordinate: | |||
| 34 | 34 | ||
| 35 | 35 | ||
| 36 | class Assignment(BaseAssignment, ABC): | 36 | class Assignment(BaseAssignment, ABC): |
| 37 | rope_length = NotImplemented | ||
| 38 | |||
| 37 | def parse_line(self, item: str) -> Tuple[str, int]: | 39 | def parse_line(self, item: str) -> Tuple[str, int]: |
| 38 | direction, amount = item.split(" ") | 40 | direction, amount = item.split(" ") |
| 39 | return direction, int(amount) | 41 | return direction, int(amount) |
| @@ -54,7 +56,7 @@ class Assignment(BaseAssignment, ABC): | |||
| 54 | head.y -= 1 | 56 | head.y -= 1 |
| 55 | 57 | ||
| 56 | @staticmethod | 58 | @staticmethod |
| 57 | def next_tail(head: Coordinate, tail: Coordinate): | 59 | def next_knot(head: Coordinate, tail: Coordinate): |
| 58 | delta = head - tail | 60 | delta = head - tail |
| 59 | 61 | ||
| 60 | if abs(delta.x) > 1 and delta.y == 0: | 62 | if abs(delta.x) > 1 and delta.y == 0: |
| @@ -62,37 +64,43 @@ class Assignment(BaseAssignment, ABC): | |||
| 62 | if abs(delta.x) > 1 and abs(delta.y) == 1: | 64 | if abs(delta.x) > 1 and abs(delta.y) == 1: |
| 63 | tail.x += delta.x - delta.polarity_x | 65 | tail.x += delta.x - delta.polarity_x |
| 64 | tail.y += delta.y | 66 | tail.y += delta.y |
| 65 | if abs(delta.y > 1) and delta.x == 0: | 67 | if abs(delta.y) > 1 and delta.x == 0: |
| 66 | tail.y += delta.y - delta.polarity_y | 68 | tail.y += delta.y - delta.polarity_y |
| 67 | if abs(delta.y) > 1 and abs(delta.x) == 1: | 69 | if abs(delta.y) > 1 and abs(delta.x) == 1: |
| 68 | tail.y += delta.y - delta.polarity_y | 70 | tail.y += delta.y - delta.polarity_y |
| 69 | tail.x += delta.x | 71 | tail.x += delta.x |
| 70 | 72 | ||
| 71 | def tail_positions(self, input: Iterator[str]) -> Iterator[Coordinate]: | 73 | def tail_positions(self, input: Iterator[str], length: int) -> Iterator[Coordinate]: |
| 72 | head = Coordinate(0, 0) | 74 | knots = [Coordinate(0, 0) for _ in range(length)] |
| 73 | tail = Coordinate(0, 0) | ||
| 74 | 75 | ||
| 75 | for line in input: | 76 | for line in input: |
| 76 | direction, amount = self.parse_line(line) | 77 | direction, amount = self.parse_line(line) |
| 77 | 78 | ||
| 78 | for _ in range(amount): | 79 | for _ in range(amount): |
| 79 | self.next_head(head, direction) | 80 | for index in range(length): |
| 80 | self.next_tail(head, tail) | 81 | if index == 0: |
| 81 | yield tail | 82 | self.next_head(knots[index], direction) |
| 83 | continue | ||
| 84 | |||
| 85 | self.next_knot(knots[index - 1], knots[index]) | ||
| 86 | |||
| 87 | yield knots[length - 1] | ||
| 82 | 88 | ||
| 83 | def unique_tail_positions(self, input: Iterator[str]) -> Set[Coordinate]: | 89 | def unique_tail_positions( |
| 90 | self, input: Iterator[str], length: int | ||
| 91 | ) -> Set[Coordinate]: | ||
| 84 | unique_tail_positions = set() | 92 | unique_tail_positions = set() |
| 85 | 93 | ||
| 86 | for position in self.tail_positions(input): | 94 | for position in self.tail_positions(input, length): |
| 87 | unique_tail_positions.add(copy(position)) | 95 | unique_tail_positions.add(copy(position)) |
| 88 | 96 | ||
| 89 | return unique_tail_positions | 97 | return unique_tail_positions |
| 90 | 98 | ||
| 91 | def visualize(self, width: int, height: int, positions: Set[Coordinate]): | 99 | def visualize(self, width: range, height: range, positions: Set[Coordinate]): |
| 92 | rows = [] | 100 | rows = [] |
| 93 | for y in range(height): | 101 | for y in height: |
| 94 | items = [] | 102 | items = [] |
| 95 | for x in range(width): | 103 | for x in width: |
| 96 | if x == 0 and y == 0: | 104 | if x == 0 and y == 0: |
| 97 | items.append("s") | 105 | items.append("s") |
| 98 | elif Coordinate(x, y) in positions: | 106 | elif Coordinate(x, y) in positions: |
| @@ -103,17 +111,16 @@ class Assignment(BaseAssignment, ABC): | |||
| 103 | 111 | ||
| 104 | return "\n".join(["".join(row) for row in reversed(rows)]) | 112 | return "\n".join(["".join(row) for row in reversed(rows)]) |
| 105 | 113 | ||
| 114 | def run(self, input: Iterator) -> int: | ||
| 115 | unique_positions = self.unique_tail_positions(input, length=self.rope_length) | ||
| 116 | return len(unique_positions) | ||
| 117 | |||
| 106 | 118 | ||
| 107 | class AssignmentOne(Assignment): | 119 | class AssignmentOne(Assignment): |
| 108 | example_result = 13 | 120 | example_result = 13 |
| 109 | 121 | rope_length = 2 | |
| 110 | def run(self, input: Iterator) -> int: | ||
| 111 | unique_positions = self.unique_tail_positions(input) | ||
| 112 | print() | ||
| 113 | print(self.visualize(6, 5, unique_positions)) | ||
| 114 | |||
| 115 | return len(unique_positions) | ||
| 116 | 122 | ||
| 117 | 123 | ||
| 118 | class AssignmentTwo(Assignment): | 124 | class AssignmentTwo(Assignment): |
| 119 | pass | 125 | example_result = 36 |
| 126 | rope_length = 10 | ||
