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)classDir(IntEnum):X=0N=-LARGEURS=LARGEURE=1O=-1deftuile(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 tuyauvers_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_indata]start=data.index("S")explored={start}explorer,direction=list((start+direction,direction)fordirectioninDirifdirectionandCarte[start+direction][direction])[0]whileTrue:explored.add(explorer)direction=Carte[explorer][direction]explorer=explorer+directionifexplorer==start:breakex1=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.
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 :
# Une solution assez élégante, je trouve.
Posté par Yth (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 :
Pour la suite, j'ai dû voir les choses et donc représenter mon bidule plus visuellement, on remplace
|-LJ7Fpar│─└┘┐┌. J'ai totalement triché en remplaçantSpar 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.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.