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)

def f1(row):
    return compter(grille, (row,0,0,1))
def f2(row):
     return compter(grille, (row,len(grille[0])-1,0,-1))
def f3(col):
    return compter(grille, (0,col,1,0))
def f4(col):
    return compter(grille, (len(grille)-1,col,-1,0))

from multiprocessing import Pool
if __name__ == '__main__':
    nbs_actives: list[int] = []
    with Pool() as pool:
        nbs_actives.extend(pool.map(f1, range(len(grille))))
        nbs_actives.extend(pool.map(f2, range(len(grille))))
        nbs_actives.extend(pool.map(f3, range(len(grille[0]))))
        nbs_actives.extend(pool.map(f4, range(len(grille[0]))))

    print("Réponse partie 1:", compter(grille,(0,0,0,1)))
    print("Réponse partie 2:", max(nbs_actives))