• [^] # Re: En Python, modélisé

    Posté par (site web personnel) . En réponse au message Avent du Code, jour 9. Évalué à 3. Dernière modification le 09 décembre 2022 à 16:58.

    Bon, en fait, pas besoin d'énumérer de façon aussi laborieuse bien sûr :

    from __future__ import annotations
    from enum import Enum
    from typing import Iterable, Iterator, Set, Tuple
    Coords = Tuple[int, int]
    class Direction(Enum):
     O = ( 0, 0)
     U = ( 0, 1)
     D = ( 0, -1)
     L = (-1, 0)
     R = ( 1, 0)
     def __init__(self, dx, dy):
     self.dx = dx
     self.dy = dy
    class Knot:
     def __init__(self, x: int, y: int):
     self.x = x
     self.y = y
     @property
     def coords(self) -> Coords:
     return (self.x, self.y)
     def move(self, direction: Direction) -> None:
     self.x += direction.dx
     self.y += direction.dy
     def dist(self, other: Knot) -> int:
     return max(abs(self.x - other.x), abs(self.y - other.y))
     def follow(self, other: Knot) -> None:
     if self.dist(other) <= 1:
     return
     if self.x < other.x:
     self.x += 1
     if self.x > other.x:
     self.x -= 1
     if self.y < other.y:
     self.y += 1
     if self.y > other.y:
     self.y -= 1
    class Rope:
     def __init__(self, n_knots: int) -> None:
     self.knots = [Knot(0, 0) for _ in range(n_knots)]
     @property
     def head(self) -> Knot:
     return self.knots[0]
     @property
     def tail(self) -> Knot:
     return self.knots[-1]
     def move(self, direction: Direction) -> None:
     self.head.move(direction)
     for i in range(1, len(self.knots)):
     leader = self.knots[i - 1]
     follower = self.knots[i]
     follower.follow(leader)
    def import_lines(lines: Iterable[str]) -> Iterator[Direction]:
     for line in lines:
     word1, word2 = line.split()
     direction = Direction[word1]
     repeat = int(word2)
     for _ in range(repeat):
     yield direction
    def solve_both(lines: Iterable[str]) -> Tuple[int, int]:
     """Solve both parts of today's puzzle"""
     rope = Rope(10)
     visited1 = set() # type: Set[Coords]
     visited2 = set() # type: Set[Coords]
     for direction in import_lines(lines):
     rope.move(direction)
     visited1.add(rope.knots[1].coords)
     visited2.add(rope.tail.coords)
     return len(visited1), len(visited2)