summaryrefslogtreecommitdiffstats
path: root/day9/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'day9/__init__.py')
-rw-r--r--day9/__init__.py49
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
36class Assignment(BaseAssignment, ABC): 36class 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
107class AssignmentOne(Assignment): 119class 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
118class AssignmentTwo(Assignment): 124class AssignmentTwo(Assignment):
119 pass 125 example_result = 36
126 rope_length = 10