Advent of code

 16 décembre 2023 

  The Floor Will Be Lava : Suivre le parcours d'un laser avec miroirs qui dévient ou qui scindent
\..\.....-.......
   
...............-.
   
-..............|.
   
.................
   
         
  1. code.py
  2. code_multiproc.py
f = open("input.txt", 'r', encoding='utf-8')

Grille = list[str]
PositionVitesse = tuple[int,int,int,int]
Coordonnees = tuple[int,int]

grille: Grille = [line[:-1] for line in f.readlines()]



def beam(grille: Grille, pos_vitesse, rayons, actives, anciens_passages) -> None:
    # Évitons de parcourir à l'infini les cycles de laser
    if pos_vitesse in anciens_passages:
        return
    else:
        anciens_passages.add(pos_vitesse)
    
    row, col, dir_row, dir_col = pos_vitesse
    
    # The outside is lava
    if row not in range(len(grille)) or col not in range(len(grille[0])):
        return

    actives.add( (row, col) )
   
    symb = grille[row][col]

    if symb == '.' or (symb == '|' and dir_row) or (symb == '-' and dir_col):
        beam(grille, (row+dir_row, col+dir_col, dir_row, dir_col), rayons, actives, anciens_passages)
        return

    elif symb == '-':
        rayons.append((row, col-1, 0, -1))
        rayons.append((row, col+1, 0,  1))
        return
    
    elif symb == '|':
        rayons.append((row-1, col, -1, 0))
        rayons.append((row+1, col,  1, 0))
        return

    elif symb == '/':
        dir_row, dir_col = -dir_col, -dir_row
    elif symb == '\\':
        dir_row, dir_col = dir_col, dir_row
    else:
        assert False, "'" + symb + "' est un caractère quelque peu inattendu." 

    beam(grille, (row+dir_row, col+dir_col, dir_row, dir_col), rayons, actives, anciens_passages)

     
        
    

def compter(grille: Grille, pos_vitesse: PositionVitesse) -> int:
    actives: set[Coordonnees] = set()
    anciens_passages: set[PositionVitesse] = set()
    rayons: list[PositionVitesse] = []
    rayons.append( pos_vitesse )
    while rayons:
        beam(grille, rayons.pop(), rayons, actives, anciens_passages)
    return len(actives)

nbs_actives: list[int] = []
for row in range(len(grille)):
    nbs_actives.append( compter(grille, (row, 0,              0,  1)) )
    nbs_actives.append( compter(grille, (row, len(grille[0])-1, 0, -1)) )
for col in range(len(grille[0])):
    nbs_actives.append( compter(grille, (0,           col,  1, 0)) )
    nbs_actives.append( compter(grille, (len(grille)-1, col, -1, 0)) )


print("Réponse partie 1:", nbs_actives[0])
print("Réponse partie 2:", max(nbs_actives))