from __future__ import annotations from tools.aoc import AOCDay from tools.coordinate import Coordinate, Polygon from typing import Any, Iterable DIRECTIONS = [Coordinate(1, 0), Coordinate(0, 1), Coordinate(-1, 0), Coordinate(0, -1)] DIR_TRANS = {"R": 0, "D": 1, "L": 2, "U": 3} class Day(AOCDay): inputs = [ [ (62, "input18_test"), (237, "input18_test2"), (227, "input18_test3"), (54, "input18_test4"), (50603, "input18"), ], [ (952408144115, "input18_test"), (96556251590677, "input18"), ], ] def parse_input(self, part2: bool = False) -> Iterable[tuple[int, int]]: for line in self.getInput(): d, s, c = line.split() if not part2: yield DIR_TRANS[d], int(s) else: yield int(c[-2]), int(c[2:-2], 16) def get_lagoon_area(self, part2: bool = False) -> int: start = Coordinate(0, 0) points = [] for d, l in self.parse_input(part2): end = start + DIRECTIONS[d] * l points.append(end) start = end p = Polygon(points) return int(p.get_area()) + int(p.get_circumference()) // 2 + 1 def part1(self) -> Any: return self.get_lagoon_area() def part2(self) -> Any: return self.get_lagoon_area(part2=True) if __name__ == "__main__": day = Day(2023, 18) day.run(verbose=True)