• # Un grand classique, mais toujour aussi long à résoudre

    Posté par . En réponse au message Advent of Code 2023 : Jour 10. Évalué à 2. Dernière modification le 10 décembre 2023 à 14:41.

    Quand j'ai vu que l'énoncé nous demandait de définir une boucle fermée, j'ai tout de suite senti qu'on allait devoir en calculer l'aire dans la partie suivante.
    Je ne me suis pas trompé.
    Dans la partie une, une récursion sur toute la boucle suffit (en augmentant la limite de récursion).
    Ma logique pour la partie deux est que certains motifs nous font entrer ou sortir de la boucle, il suffit de les repérer en parcourant toute la carte.
    Et beaucoup de gestion d'erreur pour repérer les erreurs de logique quand on code ou pour ne pas avoir à tester les longueurs des chaînes.
    Voici mon code :

    #!/bin/python3
    import sys
    sys.setrecursionlimit(10000)
    def getStart(puzzle):
     for i,l in enumerate(puzzle):
     for j,p in enumerate(l):
     if p == "S":
     return [i,j]
    def initLoop(puzzle,countpipes=True,get_connections=False):
     start = getStart(puzzle)
     direction = ""
     connections = ""
     go_away = [0,0]
     try:
     if puzzle[start[0]-1][start[1]] in ["F","7","|"]:
     direction = "H"
     connections += direction
     go_away = [-1,0]
     except IndexError:
     pass
     try:
     if puzzle[start[0]][start[1]-1] in ["F","L","-"]:
     direction = "G"
     connections += direction
     go_away = [0,-1]
     except IndexError:
     pass
     try:
     if puzzle[start[0]][start[1]+1] in ["J","7","-"]:
     direction = "D"
     connections += direction
     go_away = [0,1]
     except IndexError:
     pass
     try:
     if puzzle[start[0]+1][start[1]] in ["J","L","|"]:
     direction = "B"
     connections += direction
     go_away = [1,0]
     except IndexError:
     pass
     start = [start[0]+go_away[0],start[1]+go_away[1]]
     if get_connections:
     return connections
     if countpipes:
     pipes.append(start)
     return round((browseLoop(puzzle, start, direction,countpipes)+1)/2)
    def browseLoop(puzzle, start, direction, countpipes=True):
     here = puzzle[start[0]][start[1]]
     if here == "-":
     if direction == "D":
     start = [start[0],start[1]+1]
     elif direction == "G":
     start = [start[0],start[1]-1]
     else:
     raise ValueError
     elif here == "|":
     if direction == "H":
     start = [start[0]-1,start[1]]
     elif direction == "B":
     start = [start[0]+1,start[1]]
     else:
     raise ValueError
     elif here == "L":
     if direction == "B":
     start = [start[0],start[1]+1]
     direction = "D"
     elif direction == "G":
     start = [start[0]-1,start[1]]
     direction = "H"
     else:
     raise ValueError
     elif here == "F":
     if direction == "H":
     start = [start[0],start[1]+1]
     direction = "D"
     elif direction == "G":
     start = [start[0]+1,start[1]]
     direction = "B"
     else:
     raise ValueError
     elif here == "7":
     if direction == "D":
     start = [start[0]+1,start[1]]
     direction = "B"
     elif direction == "H":
     start = [start[0],start[1]-1]
     direction = "G"
     else:
     raise ValueError
     elif here == "J":
     if direction == "D":
     start = [start[0]-1,start[1]]
     direction = "H"
     elif direction == "B":
     start = [start[0],start[1]-1]
     direction = "G"
     else:
     raise ValueError
     else:
     raise ValueError
     if countpipes:
     pipes.append(start)
     if puzzle[start[0]][start[1]] == "S":
     return 1
     else:
     return browseLoop(puzzle,start,direction)+1
    def areConnected(somepipes):
     if somepipes[0] not in ["F","L"]:
     return False
     if not all([i=="-" for i in somepipes[1:-1]]):
     return False
     if somepipes[-1] not in ["7","J"]:
     return False
     if somepipes[0] == "F" and somepipes[-1] == "J":
     return True
     if somepipes[0] == "L" and somepipes[-1] == "7":
     return True
     return False
    def floodPipes(puzzle):
     initLoop(puzzle,countpipes=True)
     connections = initLoop(puzzle,get_connections=True)
     start = getStart(puzzle)
     restart = ""
     if all([c in "HB" for c in connections]):
     restart = "|"
     elif all([c in "GD" for c in connections]):
     restart = "-"
     elif all([c in "HD" for c in connections]):
     restart = "L"
     elif all([c in "BD" for c in connections]):
     restart = "F"
     elif all([c in "HG" for c in connections]):
     restart = "J"
     elif all([c in "BG" for c in connections]):
     restart = "7"
     else:
     print(connections)
     raise ValueError
     puzzle[start[0]] = puzzle[start[0]].replace("S",restart)
     inloop = False
     surface = 0
     for i, l in enumerate(puzzle):
     inloop == False
     for j, p in enumerate(l):
     if [i,j] in pipes:
     if puzzle[i][j] == "|":
     inloop = not inloop
     elif puzzle[i][j] in ["J","7"]:
     r = puzzle[i][j]
     iterator = j
     try:
     while puzzle[i][iterator] not in ["F","L"]:
     iterator -= 1
     r = puzzle[i][iterator] + r
     except IndexError:
     pass
     if areConnected(r):
     inloop = not inloop
     elif inloop:
     surface += 1
     return surface
    def solve1(puzzle,testing=False):
     s=0
     s = initLoop(puzzle)
     if testing:
     print(s)
     return s
    def solve2(puzzle,testing=False):
     global pipes
     pipes = []
     s = 0
     s = floodPipes(puzzle)
     if testing:
     print(s)
     return s

    L'informatique n'est pas une science exacte, on n'est jamais à l'abri d'un succès