Advent of code

 14 décembre 2022 

  Regolith Reservoir : Simuler du sable qui tombe sur des obstacles
490,23 -> 490,17 -> 490,23 -> 492,23 -> 49
   
490,23 -> 490,17 -> 490,23 -> 492,23 -> 49
   
                     
  1. animation
  2. code.py
  3. resultat_partie1.png
  4. resultat_partie2.png
VIDE = ' '
SABLE = '·'
MUR = '#'

SOURCE = [500,0]   # sera ajusté en x avec decalageX
 
##### Lecture des obstacles
coordonnesObstacles = []
f = open("input.txt", 'r')
lines = [line[:-1] for line in f.readlines()]
for line in lines:
    sommets = [tuple(map(int,coords.split(','))) for coords in line.split() if coords != "->"]
    (x0,y0) = sommets[0]
    coordonnesObstacles.append((x0,y0))
    for (x1,y1) in sommets[1:]:
        if x0 == x1:
            dir = (y0 > y1 and -1 or 1)
            for y in range(y0+dir, y1+dir, dir):
                coordonnesObstacles.append((x0,y))
        elif y0 == y1:
            dir = (x0 > x1 and -1 or 1)
            for x in range(x0+dir, x1+dir, dir):
                coordonnesObstacles.append((x,y0))
        (x0,y0) = (x1,y1)

##### Calculer des dimensions de la grille
maxy = max([p[1] for p in coordonnesObstacles])
Y_SOL = maxy + 2
HAUTEUR_GRILLE = Y_SOL + 1
LARGEUR_GRILLE = 2 * HAUTEUR_GRILLE  # largeur du cône possible sous la source
decalageX = SOURCE[0] - maxy
SOURCE[0] -= decalageX

##### Construction grille de départ avec les obstacles
grille = []
for y in range(HAUTEUR_GRILLE):
    grille.append( LARGEUR_GRILLE * [VIDE] )
grille[Y_SOL] = LARGEUR_GRILLE * [MUR]
for (x,y) in coordonnesObstacles:
    grille[y][x - decalageX] = MUR


##### Calcul des trajectoires des grains de sable
def getProchainEndroit(grille, x, y):
    for (prochainX, prochainY) in ((x,y+1), (x-1,y+1), (x+1,y+1)):
        if grille[prochainY][prochainX] == VIDE:
            return (prochainX, prochainY)
    return None

def prochaineArrivee(grille):
    prochainEndroit = SOURCE
    while prochainEndroit != None:
        (x,y) = prochainEndroit
        prochainEndroit = getProchainEndroit(grille, x, y)
    return (x,y)


##### On remplit !
plein = False
partie1Finie = False
nbGrains = 0
while not plein:
   nbGrains += 1
   (x,y) = prochaineArrivee(grille)
   if not partie1Finie and y == Y_SOL - 1:        # On touche le sol pour la première fois
       print("Réponse partie 1:", nbGrains - 1)   # Ne pas compter le grain au sol
       partie1Finie = True
   grille[y][x] = SABLE
   plein = (y == SOURCE[1])  #  [x,y] == SOURCE

print("Réponse partie 2:", nbGrains)     # sum(ligne.count(SABLE) for ligne in grille)