From bbafa72fd365769a08cbbfedfeb2dbc1b0b8738f Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Sun, 11 May 2025 01:12:58 +0100 Subject: [PATCH] 2017: d19: ex1: add solution --- 2017/d19/ex1/ex1.py | 73 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100755 2017/d19/ex1/ex1.py diff --git a/2017/d19/ex1/ex1.py b/2017/d19/ex1/ex1.py new file mode 100755 index 0000000..6cc724c --- /dev/null +++ b/2017/d19/ex1/ex1.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +import enum +import sys +from collections.abc import Iterator +from typing import NamedTuple + + +class Point(NamedTuple): + x: int + y: int + + +class Direction(enum.Enum): + UP = Point(-1, 0) + DOWN = Point(1, 0) + LEFT = Point(0, -1) + RIGHT = Point(0, 1) + + def apply(self, p: Point) -> Point: + dx, dy = self.value + return Point(p.x + dx, p.y + dy) + + def turns(self) -> Iterator["Direction"]: + match self: + case Direction.UP | Direction.DOWN: + turns = (Direction.LEFT, Direction.RIGHT) + case Direction.LEFT | Direction.RIGHT: + turns = (Direction.UP, Direction.DOWN) + yield from turns + + +def solve(input: str) -> str: + def parse(input: str) -> dict[Point, str]: + return { + Point(x, y): c + for x, line in enumerate(input.splitlines()) + for y, c in enumerate(line) + if c != " " + } + + def packet_spell(map: dict[Point, str]) -> str: + letters: list[str] = [] + # Travel starts downward, from outside the map before the first line + pos = min(map.keys(), key=lambda p: p.x) + dir = Direction.DOWN + + while True: + if (letter := map[pos]) not in ("+", "|", "-"): + letters.append(letter) + new_dir = dir + new_pos = dir.apply(pos) + if new_pos not in map: + for new_dir in dir.turns(): + if (new_pos := new_dir.apply(pos)) in map: + break + else: + # Must be the end of the line, stop looping + return "".join(letters) + dir = new_dir + pos = new_pos + + map = parse(input) + return packet_spell(map) + + +def main() -> None: + input = sys.stdin.read() + print(solve(input)) + + +if __name__ == "__main__": + main()