diff options
| author | 2022-12-17 17:17:54 +0100 | |
|---|---|---|
| committer | 2022-12-17 17:17:54 +0100 | |
| commit | 5fd442c3bba6b4c63facb6bd89ecc3a9736e1c8d (patch) | |
| tree | 7bfa9fa0971d7311272ea6f234c223093e4e9615 /day9 | |
| parent | 2d1263453d26cd2c6a64a3b6141ee0a12ddc0b11 (diff) | |
| download | 2022-5fd442c3bba6b4c63facb6bd89ecc3a9736e1c8d.tar.gz 2022-5fd442c3bba6b4c63facb6bd89ecc3a9736e1c8d.tar.bz2 2022-5fd442c3bba6b4c63facb6bd89ecc3a9736e1c8d.zip | |
Added some utilities
Diffstat (limited to 'day9')
| -rw-r--r-- | day9/__init__.py | 70 |
1 files changed, 26 insertions, 44 deletions
diff --git a/day9/__init__.py b/day9/__init__.py index e0f1d61..a2d6d82 100644 --- a/day9/__init__.py +++ b/day9/__init__.py | |||
| @@ -1,36 +1,10 @@ | |||
| 1 | # -*- coding: utf-8 -*- | 1 | # -*- coding: utf-8 -*- |
| 2 | from abc import ABC | 2 | from abc import ABC |
| 3 | from copy import copy | 3 | from copy import copy |
| 4 | from dataclasses import dataclass | ||
| 5 | from typing import Tuple, Iterator, List, Set | 4 | from typing import Tuple, Iterator, List, Set |
| 6 | 5 | ||
| 7 | from aoc import BaseAssignment | 6 | from aoc import BaseAssignment |
| 8 | 7 | from aoc.datastructures import Coordinate | |
| 9 | |||
| 10 | @dataclass | ||
| 11 | class Coordinate: | ||
| 12 | x: int | ||
| 13 | y: int | ||
| 14 | |||
| 15 | def __hash__(self): | ||
| 16 | return tuple([self.x, self.y]).__hash__() | ||
| 17 | |||
| 18 | def __sub__(self, other: "Coordinate"): | ||
| 19 | return Coordinate(self.x - other.x, self.y - other.y) | ||
| 20 | |||
| 21 | @property | ||
| 22 | def polarity_x(self): | ||
| 23 | try: | ||
| 24 | return abs(self.x) / self.x | ||
| 25 | except ZeroDivisionError: | ||
| 26 | return 0 | ||
| 27 | |||
| 28 | @property | ||
| 29 | def polarity_y(self): | ||
| 30 | try: | ||
| 31 | return abs(self.y) / self.y | ||
| 32 | except ZeroDivisionError: | ||
| 33 | return 0 | ||
| 34 | 8 | ||
| 35 | 9 | ||
| 36 | class Assignment(BaseAssignment, ABC): | 10 | class Assignment(BaseAssignment, ABC): |
| @@ -44,36 +18,44 @@ class Assignment(BaseAssignment, ABC): | |||
| 44 | pass | 18 | pass |
| 45 | 19 | ||
| 46 | @staticmethod | 20 | @staticmethod |
| 47 | def next_head(head: Coordinate, direction: str): | 21 | def next_head(head: Coordinate, direction: str) -> Coordinate: |
| 48 | match direction: | 22 | match direction: |
| 49 | case "R": | 23 | case "R": |
| 50 | head.x += 1 | 24 | return head + Coordinate(1, 0) |
| 51 | case "L": | 25 | case "L": |
| 52 | head.x -= 1 | 26 | return head + Coordinate(-1, 0) |
| 53 | case "U": | 27 | case "U": |
| 54 | head.y += 1 | 28 | return head + Coordinate(0, 1) |
| 55 | case "D": | 29 | case "D": |
| 56 | head.y -= 1 | 30 | return head + Coordinate(0, -1) |
| 57 | 31 | ||
| 58 | @staticmethod | 32 | @staticmethod |
| 59 | def next_knot(head: Coordinate, tail: Coordinate): | 33 | def next_knot(head: Coordinate, tail: Coordinate) -> Coordinate: |
| 60 | delta = head - tail | 34 | delta = head - tail |
| 61 | 35 | ||
| 62 | if abs(delta.x) < 2 and abs(delta.y) < 2: | 36 | if abs(delta.x) < 2 and abs(delta.y) < 2: |
| 63 | pass | 37 | return tail |
| 64 | elif abs(delta.x) > 1 and delta.y == 0: | 38 | elif abs(delta.x) > 1 and delta.y == 0: |
| 65 | tail.x += delta.x - delta.polarity_x | 39 | return tail + Coordinate( |
| 40 | delta.x - delta.polarity_x, | ||
| 41 | 0, | ||
| 42 | ) | ||
| 66 | elif abs(delta.x) > 1 and abs(delta.y) == 1: | 43 | elif abs(delta.x) > 1 and abs(delta.y) == 1: |
| 67 | tail.x += delta.x - delta.polarity_x | 44 | return tail + Coordinate(delta.x - delta.polarity_x, delta.y) |
| 68 | tail.y += delta.y | ||
| 69 | elif abs(delta.y) > 1 and delta.x == 0: | 45 | elif abs(delta.y) > 1 and delta.x == 0: |
| 70 | tail.y += delta.y - delta.polarity_y | 46 | return tail + Coordinate( |
| 47 | 0, | ||
| 48 | delta.y - delta.polarity_y, | ||
| 49 | ) | ||
| 71 | elif abs(delta.y) > 1 and abs(delta.x) == 1: | 50 | elif abs(delta.y) > 1 and abs(delta.x) == 1: |
| 72 | tail.y += delta.y - delta.polarity_y | 51 | return tail + Coordinate( |
| 73 | tail.x += delta.x | 52 | delta.x, |
| 53 | delta.y - delta.polarity_y, | ||
| 54 | ) | ||
| 74 | elif abs(delta.x) > 1 and abs(delta.y) > 1: | 55 | elif abs(delta.x) > 1 and abs(delta.y) > 1: |
| 75 | tail.x += delta.x - delta.polarity_x | 56 | return tail + Coordinate( |
| 76 | tail.y += delta.y - delta.polarity_y | 57 | delta.x - delta.polarity_x, delta.y - delta.polarity_y |
| 58 | ) | ||
| 77 | 59 | ||
| 78 | def tail_positions(self, input: Iterator[str], length: int) -> Iterator[Coordinate]: | 60 | def tail_positions(self, input: Iterator[str], length: int) -> Iterator[Coordinate]: |
| 79 | knots = [Coordinate(0, 0) for _ in range(length)] | 61 | knots = [Coordinate(0, 0) for _ in range(length)] |
| @@ -84,10 +66,10 @@ class Assignment(BaseAssignment, ABC): | |||
| 84 | for _ in range(amount): | 66 | for _ in range(amount): |
| 85 | for index in range(length): | 67 | for index in range(length): |
| 86 | if index == 0: | 68 | if index == 0: |
| 87 | self.next_head(knots[index], direction) | 69 | knots[0] = self.next_head(knots[0], direction) |
| 88 | continue | 70 | continue |
| 89 | 71 | ||
| 90 | self.next_knot(knots[index - 1], knots[index]) | 72 | knots[index] = self.next_knot(knots[index - 1], knots[index]) |
| 91 | 73 | ||
| 92 | yield knots[length - 1] | 74 | yield knots[length - 1] |
| 93 | 75 | ||
