Coverage for Day6 / part2.py: 94%

26 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 : 6 

8Part : 2 

9 

10Dans cette partie, les chiffres des “problèmes” sont disposés en colonnes 

11(verticalement), tandis que les opérateurs (+ ou *) apparaissent sur la dernière ligne. 

12 

13La lecture se fait **de droite à gauche** : 

14 - chaque colonne contenant des digits représente un nombre, 

15 - une colonne entièrement vide signifie que le nombre est terminé, 

16 - à ce moment, on applique l’opérateur correspondant, 

17 - puis on ajoute le résultat au total. 

18 

19On répète ce procédé pour toutes les colonnes. 

20 

21Le résultat final est la somme de tous les blocs évalués. 

22 

23La logique est : 

24 1. uniformiser la largeur des lignes, 

25 2. parcourir les colonnes de droite à gauche, 

26 3. construire les nombres, 

27 4. déclencher les opérations sur les colonnes vides, 

28 5. accumuler les résultats. 

29 

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

31""" 

32# %% ======================================================================== 

33# Imports 

34from math import prod 

35# =========================================================================== 

36 

37# %% ======================================================================== 

38# Input data 

39def get_input(day: int = 1, example: bool = False) -> list: 

40 """ 

41 Lit le fichier d'entrée pour le jour donné. 

42 

43 :param day: numéro du jour AoC 

44 :param example: True pour example.txt, False pour input.txt 

45 :return: liste des lignes du fichier 

46 """ 

47 filename = 'example.txt' if example else 'input.txt' 

48 with open(f"./Day{day}/{filename}", 'r', encoding='utf-8') as f: 

49 return [line.rstrip('\n') for line in f] 

50 

51 

52# =========================================================================== 

53 

54# %% ======================================================================== 

55# Résolution 

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

57 """ 

58 Résout la partie 2 : évaluation des problèmes lus verticalement. 

59 

60 Chaque colonne (de droite à gauche) contient les chiffres d’un nombre. 

61 Une colonne vide déclenche l’évaluation du bloc de nombres collectés, 

62 à l’aide de l'opérateur correspondant dans la dernière ligne. 

63 

64 :param data: lignes du fichier AoC 

65 :return: total des résultats des blocs 

66 """ 

67 

68 # Séparation : lignes contenant les chiffres et ligne des opérateurs 

69 digit_rows = [line.rstrip("\n") for line in data[:-1]] 

70 operator_row = data[-1].rstrip("\n") 

71 

72 # Normalisation des largeurs pour lisibilité colonne par colonne 

73 width = max(len(row) for row in digit_rows + [operator_row]) 

74 digit_rows = [row.ljust(width) for row in digit_rows] 

75 operator_row = operator_row.ljust(width) 

76 

77 # Les opérateurs sont lus de droite à gauche → on les stocke dans une pile 

78 operators = [c for c in operator_row if c != " "] 

79 

80 total = 0 # résultat final 

81 current_numbers = [] # nombres collectés dans le bloc courant 

82 

83 # Parcours des colonnes droite → gauche 

84 for col in range(width - 1, -2, -1): 

85 

86 # Cas déclencheur : colonne vide ou fin de parcours 

87 if col == -1 or all(row[col] == ' ' for row in digit_rows): 

88 

89 # On applique l’opération sur le bloc collecté 

90 op = operators.pop() 

91 

92 if op == '+': 

93 total += sum(current_numbers) 

94 elif op == '*': 94 ↛ 97line 94 didn't jump to line 97 because the condition on line 94 was always true

95 total += prod(current_numbers) 

96 else: 

97 raise ValueError(f"Opérateur inconnu : {op}") 

98 

99 # On réinitialise pour le bloc suivant 

100 current_numbers = [] 

101 

102 else: 

103 # Construction du nombre vertical 

104 digits = ''.join(row[col] for row in digit_rows).strip() 

105 current_numbers.append(int(digits)) 

106 

107 return total 

108 

109 

110# =========================================================================== 

111 

112# %% 

113if __name__ == "__main__": 

114 RESULT = solve(get_input(6, False)) 

115 

116 print("\n" + "═" * 60) 

117 print(" 🔐 Advent of Code 2025 — Day 6 | Part 2".center(60)) 

118 print("═" * 60) 

119 print(f"Grand Total : \033[96m{RESULT}\033[0m") 

120 print("═" * 60 + "\n")