Coverage for Day11 / part1.py: 100%

18 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 : 11 

8Part : 1 

9 

10Ce module implémente la résolution du problème du jour sous la forme d'une 

11exploration de graphe dirigé. Chaque ligne du fichier d'entrée décrit un 

12device et la liste des devices vers lesquels il envoie ses données. 

13 

14L’objectif est de déterminer le nombre total de chemins distincts menant du 

15device d’entrée ("you") au device de sortie ("out"). 

16 

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

18""" 

19 

20# %% ======================================================================== 

21# LECTURE DE L’INPUT 

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

23 """ 

24 Lit et retourne le contenu du fichier d'entrée externe. 

25 

26 Les fichiers sont stockés dans un dossier `DayX/` où X correspond 

27 au numéro du jour AoC. Deux fichiers peuvent exister : 

28 - example.txt : jeu de données simplifié fourni par l’énoncé 

29 - input.txt : jeu de données complet pour la soumission AoC 

30 

31 Parameters 

32 ---------- 

33 day : int, optional 

34 Numéro du jour AoC. Par défaut 1. 

35 example : bool, optional 

36 Si True, lit `example.txt`. Si False, lit `input.txt`. 

37 

38 Returns 

39 ------- 

40 list of str 

41 Liste des lignes du fichier, sans retour chariot final. 

42 """ 

43 file = "example.txt" if example else "input.txt" 

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

45 return [line.rstrip("\n") for line in f] 

46 

47# =========================================================================== 

48 

49 

50# %% ======================================================================== 

51# RÉSOLUTION 

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

53 """ 

54 Calcule le nombre total de chemins menant du device 'you' au device 'out'. 

55 

56 Le fichier d’entrée décrit un graphe dirigé où chaque device possède une 

57 liste d’outputs. À partir de ce graphe, une recherche en profondeur (DFS) 

58 est effectuée pour dénombrer tous les chemins distincts possibles. 

59 

60 Format attendu pour chaque ligne : 

61 "aaa: bbb ccc ddd" 

62 

63 où "aaa" est le device, et "bbb ccc ddd" les devices accessibles depuis lui. 

64 

65 Parameters 

66 ---------- 

67 data : list of str 

68 Liste des lignes brutes du fichier d’entrée. 

69 

70 Returns 

71 ------- 

72 int 

73 Nombre total de chemins distincts de 'you' vers 'out'. 

74 """ 

75 # Construction du graphe : {device: [liste_outputs]} 

76 server = {} 

77 for line in data: 

78 device, outputs = line.split(": ") 

79 server[device] = outputs.split() 

80 

81 # Compteur de chemins trouvés 

82 paths = 0 

83 

84 def dfs(device: str) -> None: 

85 """ 

86 Parcourt récursivement le graphe à partir d’un device. 

87 

88 Si la fonction atteint 'out', un chemin complet a été trouvé. 

89 """ 

90 nonlocal paths 

91 

92 # Condition d'arrêt : device final 

93 if device == "out": 

94 paths += 1 

95 return 

96 

97 # Exploration des sorties disponibles 

98 for nxt in server.get(device, []): 

99 dfs(nxt) 

100 

101 # Device de départ imposé par l’énoncé 

102 dfs("you") 

103 

104 return paths 

105 

106# =========================================================================== 

107 

108 

109# %% ======================================================================== 

110# MAIN 

111if __name__ == "__main__": 

112 RESULT = solve(get_input(11, True)) 

113 

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

115 print(" 🔐 Advent of Code 2025 — Day 11 | Part 1".center(60)) 

116 print("═" * 60) 

117 print(f"Résultat : \033[96m{RESULT}\033[0m") 

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

119 

120# ===========================================================================