• # Une solution assez élégante, je trouve.

    Posté par (Mastodon) . En réponse au message Advent of Code 2023 : Jour 10. Évalué à 2.

    Attention, spoiler pour ceux qui luttent sur la partie 2 !

    Partie 1

    Pour la première c'est pas très difficile, on parcours le bidule.
    J'ai très mal dormi, je me suis pris la tête à partir dans les deux directions à la fois et à trouver le moment de la rencontre, alors qu'il suffit de parcourir une seule boucle et de diviser la longueur par deux, voici un algorithme assez efficace, même si probablement trop modélisé.
    Au passage, j'ai aplati la carte pour qu'elle soit en 1 dimension, c'est plus facile, mais pas autant pour la partie 2 :

    data = stdin.read()).strip().splitlines()
    LARGEUR = len(data[0])
    HAUTEUR = len(data)
    data = "".join(data)
    class Dir(IntEnum):
     X = 0
     N = -LARGEUR
     S = LARGEUR
     E = 1
     O = -1
    def tuile(N=Dir.X, S=Dir.X, E=Dir.X, O=Dir.X, sides=None):
     return {Dir.N: N, Dir.S: S, Dir.E: E, Dir.O: O}
    # changement de direction en fonction de la direction d'entrée dans une portion de tuyau
    vers_tuile = {
     ".": tuile(),
     "S": tuile(N=Dir.N, S=Dir.S, E=Dir.E, O=Dir.O),
     "|": tuile(N=Dir.N, S=Dir.S),
     "-": tuile(E=Dir.E, O=Dir.O),
     "L": tuile(S=Dir.E, O=Dir.N),
     "J": tuile(S=Dir.O, E=Dir.N),
     "7": tuile(N=Dir.O, E=Dir.S),
     "F": tuile(N=Dir.E, O=Dir.S),
    }
    Carte = [vers_tuile[_] for _ in data]
    start = data.index("S")
    explored = {start}
    explorer, direction = list(
     (start + direction, direction)
     for direction in Dir
     if direction and Carte[start + direction][direction]
    )[0]
    while True:
     explored.add(explorer)
     direction = Carte[explorer][direction]
     explorer = explorer + direction
     if explorer == start:
     break
    ex1 = len(explored) // 2

    Pour la suite, j'ai dû voir les choses et donc représenter mon bidule plus visuellement, on remplace |-LJ7F par │─└┘┐┌. J'ai totalement triché en remplaçant S par son symbole, après avoir observé les données, mais c'est pas si difficile de déterminer ça, et le rendu sur les données de test.

    data = "".join([
     _ if p in explored else " "
     for p, _ in enumerate(data.translate(str.maketrans("|-LJ7F", "│─└┘┐┌")))
    ])
    for i in range(HAUTEUR):
     print(data[i * LARGEUR:(i + 1) * LARGEUR])
     ┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌───┐
     │└┘││││││││││││┌──┘
     └─┐└┘└┘││││││└┘└─┐ 
    ┌──┘┌──┐││└┘└┘ ┌┐┌┘ 
    └───┘┌─┘└┘ ┌┘└┘ 
     ┌─┘┌───┐ └┐ 
     ┌┘┌┐└┐┌─┘┌┐ └───┐
     └─┘└┐││┌┐│└┐┌─┐┌┐│
     ┌┘│││││┌┘└┐││└┘
     └─┘└┘└┘└──┘└┘ 
     ┌┐ 
     ┌┘│ 
    ┌┘ └┐
    │┌──┘
    └┘

    Partie 2, et maintenant pour le spoiler !

    J'ai doublé la carte et reconstruit les tuyaux manquants. Ensuite il suffit d'explorer la zone vide à l'extérieur, on peut se faufiler partout vu qu'on a créé de l'espace entre les tuyaux.
    On transforme une case en quatre cases, on garde celle d'origine, et on étend logiquement à droite et en dessous, la 4è en bas à droite étant forcément vide.
    Les cartes d'exemple doublées donnent ça :

    : ┌─, : ., :└─, :., :., :──
     . . .. .. . ..
    ..┌─┐.┌─┐.┌─┐.┌─┐.┌─┐.┌─┐.┌─┐.┌───────┐.
    ..│█│.│█│.│█│.│█│.│█│.│█│.│█│.│███████│.
    ..│█└─┘█│.│█│.│█│.│█│.│█│.│█│.│█┌─────┘.
    ..│█████│.│█│.│█│.│█│.│█│.│█│.│█│.......
    ..└───┐█└─┘█└─┘█│.│█│.│█│.│█└─┘█└───┐...
    ......│█████████│.│█│.│█│.│█████████│...
    ┌─────┘█┌─────┐█│.│█└─┘█└─┘███┌─┐█┌─┘...
    │███████│.....│█│.│███████████│.│█│.....
    └───────┘.┌───┘█└─┘█████████┌─┘.└─┘.....
    ..........│█████████████████│...........
    ......┌───┘█┌───────┐███████└─┐.........
    ......│█████│.......│█████████│.........
    ....┌─┘█┌─┐█└─┐.┌───┘█┌─┐█████└───────┐.
    ....│███│.│███│.│█████│.│█████████████│.
    ....└───┘.└─┐█│.│█┌─┐█│.└─┐█┌───┐█┌─┐█│.
    ............│█│.│█│.│█│...│█│...│█│.│█│.
    ..........┌─┘█│.│█│.│█│.┌─┘█└─┐.│█│.└─┘.
    ..........│███│.│█│.│█│.│█████│.│█│.....
    ..........└───┘.└─┘.└─┘.└─────┘.└─┘.....
    ........................................
    ....┌─┐...
    ....│█│...
    ..┌─┘█│...
    ..│███│...
    ┌─┘███└─┐.
    │███████│.
    │█┌─────┘.
    │█│.......
    └─┘.......
    ..........

    On « recompresse » ensuite en prenant les cases dont les coordonnées sont paires : (0, 0), (0, 2), (2, 2) etc.

    .┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌───┐
    .│└┘││││││││││││┌──┘
    .└─┐└┘└┘││││││└┘└─┐.
    ┌──┘┌──┐││└┘└┘█┌┐┌┘.
    └───┘┌─┘└┘████┌┘└┘..
    ...┌─┘┌───┐███└┐....
    ..┌┘┌┐└┐┌─┘┌┐██└───┐
    ..└─┘└┐││┌┐│└┐┌─┐┌┐│
    .....┌┘│││││┌┘└┐││└┘
    .....└─┘└┘└┘└──┘└┘..
    ..┌┐.
    .┌┘│.
    ┌┘█└┐
    │┌──┘
    └┘...

    Le reste c'est un décompte et hop, fini.
    Le code est plutôt moche, je le posterai plus tard quand je l'aurai rendu plus lisible.

    • Yth.