Coverage for Day4 / part2.py: 100%
27 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-12 09:47 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-12 09:47 +0000
1#! /usr/bin/env python
2# -*- coding: utf-8 -*-
4"""
5Advent Of Code 2025
6===================
7Day : 4
8Part : 2
10Ce script simule la suppression progressive des rouleaux de papier ("@") :
11- Un rouleau est considéré accessible si moins de 4 voisins (sur 8 possibles)
12 sont également des rouleaux.
13- Tous les rouleaux accessibles peuvent être retirés simultanément.
14- Leur retrait peut rendre accessibles d'autres rouleaux.
15- Le processus se poursuit jusqu'à ce qu'aucun nouveau rouleau ne puisse être retiré.
17Le résultat final correspond au nombre total de rouleaux retirés.
19.. codeauthor:: Alexandre Condette <alexandre.condette@wanadoo.fr>
20"""
22# %% ========================================================================
23# Imports
25# ===========================================================================
27# %% =
28# Constantes
29NEIGHBORS: list = [
30 (-1, -1), (-1, 0), (-1, 1),
31 (0, -1), (0, 1),
32 (1, -1), (1, 0), (1, 1)
33]
34# ==
35# %% ========================================================================
36# Input data
37def get_input(day: int = 1, example: bool = False) -> list:
38 """
39 Lit le fichier d'input pour le jour donné.
41 :param day: numéro du jour AOC
42 :param example: si True, utilise le fichier example.txt sinon input.txt
43 :return: liste de lignes du fichier
44 :rtype: list
45 """
46 file = 'example.txt' if example else 'input.txt'
47 with open(f"./Day{day}/{file}", 'r', encoding='utf-8') as f:
48 return [line.rstrip('\n') for line in f]
50# ===========================================================================
52# %% ========================================================================
53# Résolution
54def solve(data: list) -> int:
55 """
56 Simule les suppressions successives des rouleaux accessibles (<4 voisins)
57 jusqu'à stabilisation.
59 :param data: Liste brute des lignes d’input.
60 :return: Nombre total de rouleaux retirés.
61 :rtype: int
62 """
63 # --- Construction de l'ensemble des rouleaux "@"
64 paper_rolls = set()
65 for y, line in enumerate(data):
66 for x, c in enumerate(line):
67 if c == "@":
68 paper_rolls.add((y, x))
70 total_removed = 0
72 while True:
73 to_remove = set()
75 # Identifier les rouleaux accessibles (moins de 4 voisins)
76 for (y, x) in paper_rolls:
77 neighbor_count = 0
78 for dy, dx in NEIGHBORS:
79 neighbor = (y + dy, x + dx)
80 if neighbor in paper_rolls:
81 neighbor_count += 1
82 if neighbor_count < 4:
83 to_remove.add((y, x))
85 # Plus rien à retirer ? On a atteint la stabilité
86 if not to_remove:
87 break
89 # Retirer tous les rouleaux accessibles en un tour
90 paper_rolls -= to_remove
91 total_removed += len(to_remove)
93 return total_removed
95# ===========================================================================
97# %%
98if __name__ == "__main__":
99 RESULT = solve(get_input(4, False))
101 print("\n" + "═" * 60)
102 print(" 🔐 Advent of Code 2025 — Day 4 | Part 2".center(60))
103 print("═" * 60)
104 print(f"Rouleaux retirés : \033[96m{RESULT}\033[0m")
105 print("═" * 60 + "\n")