From 0af1b042a29811bc5c850267681dc45469981845 Mon Sep 17 00:00:00 2001 From: Tom van der Lee Date: Mon, 12 Dec 2022 08:51:41 +0100 Subject: Day 9 [WIP] --- day9/__init__.py | 49 ++++++++++-------- day9/example.txt | 8 --- day9/example_part_1.txt | 8 +++ day9/example_part_2.txt | 8 +++ day9/test_init.py | 128 +++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 164 insertions(+), 37 deletions(-) delete mode 100644 day9/example.txt create mode 100644 day9/example_part_1.txt create mode 100644 day9/example_part_2.txt (limited to 'day9') 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: class Assignment(BaseAssignment, ABC): + rope_length = NotImplemented + def parse_line(self, item: str) -> Tuple[str, int]: direction, amount = item.split(" ") return direction, int(amount) @@ -54,7 +56,7 @@ class Assignment(BaseAssignment, ABC): head.y -= 1 @staticmethod - def next_tail(head: Coordinate, tail: Coordinate): + def next_knot(head: Coordinate, tail: Coordinate): delta = head - tail if abs(delta.x) > 1 and delta.y == 0: @@ -62,37 +64,43 @@ class Assignment(BaseAssignment, ABC): if abs(delta.x) > 1 and abs(delta.y) == 1: tail.x += delta.x - delta.polarity_x tail.y += delta.y - if abs(delta.y > 1) and delta.x == 0: + if abs(delta.y) > 1 and delta.x == 0: tail.y += delta.y - delta.polarity_y if abs(delta.y) > 1 and abs(delta.x) == 1: tail.y += delta.y - delta.polarity_y tail.x += delta.x - def tail_positions(self, input: Iterator[str]) -> Iterator[Coordinate]: - head = Coordinate(0, 0) - tail = Coordinate(0, 0) + def tail_positions(self, input: Iterator[str], length: int) -> Iterator[Coordinate]: + knots = [Coordinate(0, 0) for _ in range(length)] for line in input: direction, amount = self.parse_line(line) for _ in range(amount): - self.next_head(head, direction) - self.next_tail(head, tail) - yield tail + for index in range(length): + if index == 0: + self.next_head(knots[index], direction) + continue + + self.next_knot(knots[index - 1], knots[index]) + + yield knots[length - 1] - def unique_tail_positions(self, input: Iterator[str]) -> Set[Coordinate]: + def unique_tail_positions( + self, input: Iterator[str], length: int + ) -> Set[Coordinate]: unique_tail_positions = set() - for position in self.tail_positions(input): + for position in self.tail_positions(input, length): unique_tail_positions.add(copy(position)) return unique_tail_positions - def visualize(self, width: int, height: int, positions: Set[Coordinate]): + def visualize(self, width: range, height: range, positions: Set[Coordinate]): rows = [] - for y in range(height): + for y in height: items = [] - for x in range(width): + for x in width: if x == 0 and y == 0: items.append("s") elif Coordinate(x, y) in positions: @@ -103,17 +111,16 @@ class Assignment(BaseAssignment, ABC): return "\n".join(["".join(row) for row in reversed(rows)]) + def run(self, input: Iterator) -> int: + unique_positions = self.unique_tail_positions(input, length=self.rope_length) + return len(unique_positions) + class AssignmentOne(Assignment): example_result = 13 - - def run(self, input: Iterator) -> int: - unique_positions = self.unique_tail_positions(input) - print() - print(self.visualize(6, 5, unique_positions)) - - return len(unique_positions) + rope_length = 2 class AssignmentTwo(Assignment): - pass + example_result = 36 + rope_length = 10 diff --git a/day9/example.txt b/day9/example.txt deleted file mode 100644 index 9874df2..0000000 --- a/day9/example.txt +++ /dev/null @@ -1,8 +0,0 @@ -R 4 -U 4 -L 3 -D 1 -R 4 -D 1 -L 5 -R 2 diff --git a/day9/example_part_1.txt b/day9/example_part_1.txt new file mode 100644 index 0000000..9874df2 --- /dev/null +++ b/day9/example_part_1.txt @@ -0,0 +1,8 @@ +R 4 +U 4 +L 3 +D 1 +R 4 +D 1 +L 5 +R 2 diff --git a/day9/example_part_2.txt b/day9/example_part_2.txt new file mode 100644 index 0000000..60bd43b --- /dev/null +++ b/day9/example_part_2.txt @@ -0,0 +1,8 @@ +R 5 +U 8 +L 8 +D 3 +R 17 +D 10 +L 25 +U 20 diff --git a/day9/test_init.py b/day9/test_init.py index b36eed6..eb889c7 100644 --- a/day9/test_init.py +++ b/day9/test_init.py @@ -4,11 +4,123 @@ import os.path import day9 -def test_output_visualization(): - expected = "..##..\n" "...##.\n" ".####.\n" "....#.\n" "s###.." - - assignment = day9.AssignmentOne(path=os.path.dirname(day9.__file__)) - unique_positions = assignment.unique_tail_positions( - input=assignment.read_input(True) - ) - assert expected == assignment.visualize(6, 5, unique_positions) +class TestAssignment: + def test_right(self): + expected = "\n".join( + [ + "s###..", + ] + ) + + input = ["R 4"] + + assignment = day9.AssignmentOne(path=os.path.dirname(day9.__file__)) + unique_positions = assignment.unique_tail_positions(input=input, length=2) + + assert assignment.visualize(range(6), range(1), unique_positions) == expected + + def test_left(self): + expected = "\n".join( + [ + "..###s", + ] + ) + + input = ["L 4"] + + assignment = day9.AssignmentOne(path=os.path.dirname(day9.__file__)) + unique_positions = assignment.unique_tail_positions(input=input, length=2) + + assert ( + assignment.visualize(range(-5, 1), range(1), unique_positions) == expected + ) + + def test_up(self): + expected = "\n".join( + [ + ".", + ".", + "#", + "#", + "#", + "s", + ] + ) + + input = ["U 4"] + + assignment = day9.AssignmentOne(path=os.path.dirname(day9.__file__)) + unique_positions = assignment.unique_tail_positions(input=input, length=2) + + assert assignment.visualize(range(1), range(6), unique_positions) == expected + + def test_down(self): + expected = "\n".join( + [ + "s", + "#", + "#", + "#", + ".", + ".", + ] + ) + + input = ["D 4"] + + assignment = day9.AssignmentOne(path=os.path.dirname(day9.__file__)) + unique_positions = assignment.unique_tail_positions(input=input, length=2) + + assert ( + assignment.visualize(range(1), range(-5, 1), unique_positions) == expected + ) + + +class TestAssignmentOne: + def test_output_visualization(self): + expected = "\n".join(["..##..", "...##.", ".####.", "....#.", "s###.."]) + + assignment = day9.AssignmentOne(path=os.path.dirname(day9.__file__)) + unique_positions = assignment.unique_tail_positions( + input=assignment.read_input(True), length=2 + ) + assert assignment.visualize(range(6), range(5), unique_positions) == expected + + +class TestAssignmentTwo: + def test_output_visualization(self): + expected = "\n".join( + [ + "..........................", + "..........................", + "..........................", + "..........................", + "..........................", + "..........................", + "..........................", + "..........................", + "..........................", + "#.........................", + "#.............###.........", + "#............#...#........", + ".#..........#.....#.......", + "..#..........#.....#......", + "...#........#.......#.....", + "....#......s.........#....", + ".....#..............#.....", + "......#............#......", + ".......#..........#.......", + "........#........#........", + ".........########.........", + ] + ) + + assignment = day9.AssignmentTwo(path=os.path.dirname(day9.__file__)) + unique_positions = assignment.unique_tail_positions( + input=assignment.read_input(True), + length=10, + ) + assert ( + assignment.visualize(range(-11, 15), range(-5, 16), unique_positions) + == expected + ) -- cgit v1.2.3