Coverage for Day6 / part2.py: 94%
26 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 : 6
8Part : 2
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.
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.
19On répète ce procédé pour toutes les colonnes.
21Le résultat final est la somme de tous les blocs évalués.
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.
30.. codeauthor:: Alexandre Condette <alexandre.condette@wanadoo.fr>
31"""
32# %% ========================================================================
33# Imports
34from math import prod
35# ===========================================================================
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é.
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]
52# ===========================================================================
54# %% ========================================================================
55# Résolution
56def solve(data: list) -> int:
57 """
58 Résout la partie 2 : évaluation des problèmes lus verticalement.
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.
64 :param data: lignes du fichier AoC
65 :return: total des résultats des blocs
66 """
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")
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)
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 != " "]
80 total = 0 # résultat final
81 current_numbers = [] # nombres collectés dans le bloc courant
83 # Parcours des colonnes droite → gauche
84 for col in range(width - 1, -2, -1):
86 # Cas déclencheur : colonne vide ou fin de parcours
87 if col == -1 or all(row[col] == ' ' for row in digit_rows):
89 # On applique l’opération sur le bloc collecté
90 op = operators.pop()
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}")
99 # On réinitialise pour le bloc suivant
100 current_numbers = []
102 else:
103 # Construction du nombre vertical
104 digits = ''.join(row[col] for row in digit_rows).strip()
105 current_numbers.append(int(digits))
107 return total
110# ===========================================================================
112# %%
113if __name__ == "__main__":
114 RESULT = solve(get_input(6, False))
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")