Coverage for Day7 / part1.py: 80%
38 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 : 7
8Part : 1
10Ce script simule la propagation d’un faisceau lumineux depuis un point
11d’entrée marqué par 'S'. Le faisceau descend ligne par ligne.
13Lorsque le faisceau rencontre un splitter '^', il :
14 - compte une occurrence,
15 - se divise en deux faisceaux (gauche et droite).
17Les faisceaux continuent leur propagation jusqu’à la fin de la carte ou
18jusqu’à ce qu’aucun faisceau ne reste actif.
20Le résultat correspond au nombre total de splitters traversés.
22.. codeauthor:: Alexandre Condette <alexandre.condette@wanadoo.fr>
23"""
26# %% ========================================================================
27# Input data
28def get_input(day: int = 1, example: bool = False) -> list:
29 """
30 Lit le fichier d'entrée pour le jour donné.
32 :param day: numéro du jour AoC
33 :param example: True pour example.txt, False pour input.txt
34 :return: liste des lignes du fichier
35 """
36 filename = 'example.txt' if example else 'input.txt'
37 with open(f"./Day{day}/{filename}", '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 Simule les faisceaux descendants depuis 'S' et compte les splitters '^'.
48 :param data: liste de lignes décrivant la carte
49 :return: nombre total de splitters rencontrés
50 """
52 # Préparation des lignes
53 rows = [line.rstrip("\n") for line in data]
54 height = len(rows)
55 if height == 0: 55 ↛ 56line 55 didn't jump to line 56 because the condition on line 55 was never true
56 return 0
58 width = max(len(r) for r in rows)
59 grid = [r.ljust(width, " ") for r in rows]
61 # Recherche de la position de 'S'
62 start_row = start_col = None
63 for i, row in enumerate(grid): 63 ↛ 69line 63 didn't jump to line 69 because the loop on line 63 didn't complete
64 if "S" in row: 64 ↛ 63line 64 didn't jump to line 63 because the condition on line 64 was always true
65 start_row = i
66 start_col = row.index("S")
67 break
69 if start_row is None: 69 ↛ 70line 69 didn't jump to line 70 because the condition on line 69 was never true
70 raise ValueError("Point d'entrée 'S' introuvable dans l'input")
72 splits = 0
74 # Faisceaux actifs (colonnes)
75 active_beams = {start_col}
77 # Propagation ligne par ligne
78 for r in range(start_row + 1, height):
79 next_beams = set()
81 for c in active_beams:
82 if c < 0 or c >= width: 82 ↛ 83line 82 didn't jump to line 83 because the condition on line 82 was never true
83 continue
85 ch = grid[r][c]
87 # Splitter : deux faisceaux + comptage
88 if ch == "^":
89 splits += 1
90 if c - 1 >= 0: 90 ↛ 92line 90 didn't jump to line 92 because the condition on line 90 was always true
91 next_beams.add(c - 1)
92 if c + 1 < width: 92 ↛ 81line 92 didn't jump to line 81 because the condition on line 92 was always true
93 next_beams.add(c + 1)
95 else:
96 # Le faisceau continue
97 next_beams.add(c)
99 if not next_beams: 99 ↛ 100line 99 didn't jump to line 100 because the condition on line 99 was never true
100 break
102 active_beams = next_beams
104 return splits
106# ===========================================================================
108# %%
109if __name__ == "__main__":
110 RESULT = solve(get_input(7, False))
112 print("\n" + "═" * 60)
113 print(" 🔐 Advent of Code 2025 — Day 7 | Part 1".center(60))
114 print("═" * 60)
115 print(f"Résultat : \033[96m{RESULT}\033[0m")
116 print("═" * 60 + "\n")