Coverage for Day5 / part2.py: 100%
19 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 : 5
8Part : 2
10Ce script calcule le nombre total d'identifiants présents dans l'ensemble
11des intervalles définis dans la première section de l'input.
13Chaque intervalle est défini sous la forme "start-stop". La solution ne
14génère pas tous les identifiants individuellement ; elle fusionne les
15intervalles qui se chevauchent ou sont contigus, puis calcule la somme
16des longueurs des intervalles fusionnés pour obtenir le résultat final.
18Cette approche permet de gérer efficacement un très grand nombre de valeurs
19sans explosion mémoire.
21.. codeauthor:: Alexandre Condette <alexandre.condette@wanadoo.fr>
22"""
25# %% ========================================================================
26# Input data
27def get_input(day: int = 1, example: bool = False) -> list:
28 """
29 Lit le fichier d'input pour le jour donné.
31 :param day: numéro du jour AOC
32 :param example: si True, utilise le fichier example.txt sinon input.txt
33 :return: liste de lignes du fichier
34 :rtype: list
35 """
36 file = 'example.txt' if example else 'input.txt'
37 with open(f"./Day{day}/{file}", 'r', encoding='utf-8') as f:
38 return [line.rstrip('\n') for line in f]
40# ===========================================================================
42# %% ========================================================================
43# Résolution
44def solve(data: list) -> int:
45 """
46 Calcule le nombre total d'identifiants inclus dans les intervalles.
48 L'input est supposé structuré avec :
49 - Une première section contenant des intervalles "start-stop".
50 - Une section suivante contenant éventuellement d'autres informations
51 ou identifiants, qui sont ignorés dans cette partie.
53 Étapes principales :
54 1. Extraction de tous les intervalles.
55 2. Tri des intervalles par début.
56 3. Fusion des intervalles qui se chevauchent ou sont contigus.
57 4. Somme des longueurs des intervalles fusionnés pour obtenir le total.
59 :param data: Liste brute des lignes du fichier.
60 :return: Nombre total d'identifiants présents dans les intervalles.
61 :rtype: int
62 """
63 intervals: list = []
65 # 1. Collecte uniquement les intervalles
66 for line in data:
67 if "-" in line:
68 start, stop = map(int, line.split("-"))
69 intervals.append((start, stop))
70 else:
71 continue # On arrête à la fin de la section des intervalles
73 # 2. Tri des intervalles
74 intervals.sort()
76 # 3. Fusion des intervalles
77 merged = []
78 for start, stop in intervals:
79 if not merged or start > merged[-1][1] + 1:
80 merged.append([start, stop])
81 else:
82 merged[-1][1] = max(merged[-1][1], stop)
84 # 4. Calcul du nombre total d'identifiants
85 fresh = sum(stop - start + 1 for start, stop in merged)
87 return fresh
89# ===========================================================================
91# %%
92if __name__ == "__main__":
93 RESULT = solve(get_input(5, False))
95 print("\n" + "═" * 60)
96 print(" 🔐 Advent of Code 2025 — Day 5 | Part 2".center(60))
97 print("═" * 60)
98 print(f"Ingrédients frais : \033[96m{RESULT}\033[0m")
99 print("═" * 60 + "\n")