• [^] # Re: Mes conseils...

    Posté par (Mastodon) . En réponse au message Avent du Code, jour 23. Évalué à 2. Dernière modification le 23 décembre 2022 à 13:34.

    @dataclass(frozen=True)
    class Direction: # Sur-modélisation de la direction
     d: int
     @classmethod
     def init(cls):
     cls.N = Direction(0)
     cls.S = Direction(1)
     cls.W = Direction(2)
     cls.E = Direction(3)
     return [cls.N, cls.S, cls.W, cls.E]
     @classmethod
     @cache
     def get(cls, d):
     return cls.init()[d % 4]
     @cached_property
     def next(self):
     return Direction.get(self.d + 1)
     def __str__(self):
     return "NSWE"[self.d]
    class Elf(tuple): # Modélisation failsafe d'une position d'elfe.
     @cached_property
     def col(self):
     return self[0]
     @cached_property
     def row(self):
     return self[1]
     @cached_property
     def enw(self):
     return Elf((self.col - 1, self.row - 1))
     @cached_property
     def en(self):
     return Elf((self.col, self.row - 1))
     @cached_property
     def ene(self):
     return Elf((self.col + 1, self.row - 1))
     @cached_property
     def ew(self):
     return Elf((self.col - 1, self.row))
     @cached_property
     def ee(self):
     return Elf((self.col + 1, self.row))
     @cached_property
     def esw(self):
     return Elf((self.col - 1, self.row + 1))
     @cached_property
     def es(self):
     return Elf((self.col, self.row + 1))
     @cached_property
     def ese(self):
     return Elf((self.col + 1, self.row + 1))
     @cached_property
     def around(self):
     return {self.enw, self.en, self.ene, self.ew, self.ee, self.esw, self.es, self.ese}
     @cached_property
     def N(self):
     return {self.enw, self.en, self.ene}
     @cached_property
     def S(self):
     return {self.esw, self.es, self.ese}
     @cached_property
     def W(self):
     return {self.enw, self.ew, self.esw}
     @cached_property
     def E(self):
     return {self.ene, self.ee, self.ese}
     def look(self, d):
     return [self.N, self.S, self.W, self.E][d.d]
     def go(self, d):
     return [self.en, self.es, self.ew, self.ee][d.d]
     def choose(self, direction, elves):
     for _ in range(4):
     if self.look(direction).isdisjoint(elves):
     return self.go(direction)
     direction = direction.next
    def inputs(data):
     return {
     Elf((col, row))
     for row, r in enumerate(data.splitlines())
     for col, c in enumerate(r)
     if c == "#"
     }
    def dimension(elves):
     return (
     min(e.col for e in elves),
     max(e.col for e in elves),
     min(e.row for e in elves),
     max(e.row for e in elves),
     )
    def iteration(elves, direction, debug=False):
     considering = set()
     blocked = set()
     for elf in elves:
     if elf.around.isdisjoint(elves):
     elf.choice = None
     continue
     elf.choice = elf.choose(direction, elves)
     if not elf.choice:
     continue
     if elf.choice in considering:
     blocked.add(elf.choice)
     elf.choice = None
     else:
     considering.add(elf.choice)
     considering.difference_update(blocked)
     move = {elf for elf in elves if elf.choice in considering}
     moveto = {elf.choice for elf in move}
     elves.difference_update(move)
     elves.update(moveto)
     return len(considering)
    Direction.init()
    direction = Direction.N
    elves = inputs(sys.stdin.read())
    round = 0
    while iteration(elves, direction):
     round += 1
     direction = direction.next
     if round == 10:
     c0, c1, r0, r1 = dimension(elves)
     print(f"Empty Spaces at Round 10 = {(c1 - c0 + 1) * (r1 - r0 + 1) - len(elves)}")
    print(f"Ended at round {round+1}")

    Simple, propre, impossible de se planter, tout est clair, tout est sur-validé. Et ça fonctionne.
    Mon bug c'est parce que j'avais fait une boucle pour afficher du debug.
    Sinon j'aurais pas fait de boucle, et utiliser des set.difference/update comme dans le code présenté...
    Pfff...

    Ah, oui, partir sur une classe dérivée de tuple pour les Elfes, c'est évidemment pour pouvoir utiliser les fonctions d'ensemble, très simples et efficaces, sans avoir à coder quoi que ce soit de compliqué, ou réinventer la roue !

    • Yth.