Coverage for Day4 / part2.py: 100%

27 statements  

« 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 -*- 

3 

4""" 

5Advent Of Code 2025 

6=================== 

7Day : 4 

8Part : 2 

9 

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é. 

16 

17Le résultat final correspond au nombre total de rouleaux retirés. 

18 

19.. codeauthor:: Alexandre Condette <alexandre.condette@wanadoo.fr> 

20""" 

21 

22# %% ======================================================================== 

23# Imports 

24 

25# =========================================================================== 

26 

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é. 

40 

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] 

49 

50# =========================================================================== 

51 

52# %% ======================================================================== 

53# Résolution 

54def solve(data: list) -> int: 

55 """ 

56 Simule les suppressions successives des rouleaux accessibles (<4 voisins) 

57 jusqu'à stabilisation. 

58 

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)) 

69 

70 total_removed = 0 

71 

72 while True: 

73 to_remove = set() 

74 

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)) 

84 

85 # Plus rien à retirer ? On a atteint la stabilité 

86 if not to_remove: 

87 break 

88 

89 # Retirer tous les rouleaux accessibles en un tour 

90 paper_rolls -= to_remove 

91 total_removed += len(to_remove) 

92 

93 return total_removed 

94 

95# =========================================================================== 

96 

97# %% 

98if __name__ == "__main__": 

99 RESULT = solve(get_input(4, False)) 

100 

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")