Objectif : Lire et Analyser un sujet - Proposer une solution “brute-force” à in problème d’optimisation - Choisir les bonnes structures de données pour des problèmes simples.
Pour tous les exercices de cette session, on vous fournit un fichier
squelette Session6.java.
Les objectifs sont, dans l’ordre, que le code soit
correct, que le code soit efficace et
que le code soit lisible. Des tests unitaires
sont fournis dans Session6Test.java.
Vous devez être attentifs à la quantité de mémoire nécessaire à votre programme et vous avez le droit d’utiliser toutes les caractéristiques de l’entrée (elles sont indiquées pour chaque exercice) pour concevoir un code efficace.
Dans cette partie, vous ne devez pas utiliser de
Stream.
Avant de se lancer dans les exercice, et parce que nous pensons que
ce sera utile pour la suite, écrivez la méthode suivante qui renvoie
tous les sous-ensembles de [0..n−1]. Chaque sous ensemble est
représenté par un BitSet tel que si l’entier i
appartient au sous-ensemble, alors le bita d’indice i est
set. Il est possible de la faire récursivement, mais il y a
plus efficace. Pour vous aiguiller, on vous demande de commencer par
écrire une méthode of qui transforme un entier en un
BitSet qui correspond à sa représentation binaire. Et
d’ailleurs, avant d’écrire la méthode, pouvez-vous dire combien de
sous-ensemble elle va renvoyer, en fonction de n?
public static BitSet of(int value)
public static List<BitSet> allSubsets(int n)allSubsets(3) --> [{}, {0}, {1}, {0, 1}, {2}, {0, 2}, {1, 2}, {0, 1, 2}]

Juste de l’autre côté du couloir, se trouve une grande usine. Malheureusement, toutes les machines de l’usine sont hors service, et les ouvriers ne connaissent pas la procédure d’initialisation. Vous allez les aider.
Il existe un manuel des machines, mais la section qui détaillait la procédure d’initialisation a été arrachée. Tout ce qu’il reste du manuel, ce sont quelques schémas de voyants lumineux et des schémas de câblage des boutons (votre entrée).
.##. 3 1-3 2 2-3 0-2 0-1
.#... 0-2-3-4 2-3 0-4 0-1-2 1-2-3-4
#.###. 0-1-2-3-4 0-3-4 0-1-2-4-5 1-2
Le manuel décrit une machine par ligne. Chaque ligne contient un
unique schéma de voyants composés de # et de
., suivi d’un ou plusieurs schémas de câblage de boutons.
Les différents schémas sont séparés par des espaces.
Pour démarrer une machine, ses voyants doivent correspondre à ceux
indiqués dans le schéma, où . signifie éteint et
# signifie allumé. La machine possède le nombre de voyants
indiqué, mais tous sont initialement éteints. Sur une machine, les
voyants sont numérotés de droite à gauche en partant de 0. Par exemple,
le schéma de voyants #.###. signifie que la machine possède
6 voyants initialement éteints et que l’objectif est de configurer
simultanément les voyant 0 et 4 sur éteint et les voyants 1, 2, 3 et 5
sur allumé.
Il est possible de changer l’état des voyants en appuyant sur
n’importe lequel des boutons listés. Chaque bouton indique quels voyants
il inverse. Lorsqu’un bouton est pressé, chacun des voyants indiqués
change d’état : il s’allume s’il était éteint, et s’éteint s’il était
allumé. Par exemple, le schéma de câblage comme 0-3-4
signifie que chaque fois que ce bouton est pressé, les premier,
quatrième et cinquième voyants changent tous d’état. Si les voyants
étaient dans l’état .....#, appuyer sur ce bouton les
ferait passer à l’état .##....
Il est possible d’appuyer sur chaque bouton autant de fois que souhaité. Cependant, pour gagner du temps, il faut déterminer le nombre total minimal de pressions nécessaires pour configurer correctement tous les voyants de toutes les machines de la liste. Si les schémas de câblages ne permettent pas d’allumer tous les voyants, la machine est reste éteinte.
Analyser le schéma de voyants et les schémas de câblage des boutons
de chaque machine et écrivez la méthode factory qui renvoie
le nombre minimal de pressions nécessaires pour configurer correctement
les voyants de toutes les machines.
public static long factory(Path path) throws IOException {Caractéristiques des fichiers d’entrée :
L’entrée est un fichier contenant une machine par ligne, au format indiqué ci-dessus.
DIFFICULTÉ Niv. 1
Nombre de ligne max: 1_000
Nombre de voyants max: 5
Nombre de schémas de boutons max: 16
DIFFICULTÉ Niv. 2
Nombre de ligne max: 10_000
Nombre de voyants max: 20
Nombre de schémas de boutons max: 20
Exemple :
.##. 3 1-3 2 2-3 0-2 0-1
.#... 0-2-3-4 2-3 0-4 0-1-2 1-2-3-4
#.###. 0-1-2-3-4 0-3-4 0-1-2-4-5 1-2 --> 7
Il existe plusieurs façons de configurer correctement la première machine :
1-3, une fois sur
2-3, et deux fois sur 0-1, soit un total de 4
pressions.1-3,
soit un total de 5 pressions.Mais le nombre minimal de pressions est 2, en appuyant une fois sur
les deux derniers boutons 0-2 et 0-1.
La deuxième machine peut être configurée avec 3 pressions : une fois
sur les trois derniers boutons 0-4, 0-1-2 et
1-2-3-4.
La troisième machine possède 6 voyants. Le nombre minimal de
pressions est 2 : une fois sur les boutons 0-3-4 et
0-1-2-4-5.
Donc, le nombre minimal de pressions pour configurer correctement les voyants de toutes les machines est 2 + 3 + 2 = 7.
BitSet.
Source: https://adventofcode.com/2025/day/10

Vous effectuer des livraisons à vélo et vous être est en train de charger les 2 sacoches et votre sac à dos. Vous avez la liste des poids de tous les colis que vous devez faire tenir dedans. Les colis doivent être répartis en trois groupes de poids, de telle façon que le poids des 2 sacoches soit le double du poids du sac à dos (sinon, vous ne serez pas stable sur le vélo), et chaque colis doit être utilisé. Le premier groupe va dans le sac à dos, et les deux autres dans les sacoches.
Bien sûr, la stabilité n’est pas le seul problème. Le premier groupe doit tenir dans le sac à dos, donc il doit contenir le moins de colis possibles. Le nombre de colis dans les deux autres groupes n’a pas d’importance, tant que tous les groupes ont le même poids.
De plus, s’il existe plusieurs façons de répartir les colis de sorte que le premier groupe contienne le nombre minimal possible de colis, il faut choisir celle où le premier groupe a le plus petit enchevêtrement quantique afin de réduire le risque d’accidents (allez savoir pourquoi…). L’enchevêtrement quantique d’un groupe de colis est le produit de leurs poids, c’est-à-dire la valeur obtenue en multipliant tous leurs poids entre eux.
Par exemple, supposons qu’il y ait dix colis de poids 1 à 5, puis 7 à 11. Dans ce cas, certains premiers groupes possibles, leur enchevêtrement quantique, ainsi qu’une manière de répartir les colis restants, sont les suivants (ici les groupes 2 et 3 ont le mieme poids, mais ce n’est pas une obligation) :
Groupe 1 ; Groupe 2 ; Groupe 3
11 9 (EQ= 99) ; 10 8 2 ; 7 5 4 3 1
10 9 1 (EQ= 90) ; 11 7 2 ; 8 5 4 3
10 8 2 ; 11 9 ; 7 5 4 3 1
10 7 3 ; 11 9 ; 8 5 4 2 1
10 5 4 1 ; 11 9 ; 8 7 3 2
10 5 3 2 ; 11 9 ; 8 7 4 1
10 4 3 2 1 ; 11 9 ; 8 7 5
9 8 3 ; 11 7 2 ; 10 5 4 1
9 7 4 ; 11 8 1 ; 10 5 3 2
9 5 4 2 ; 11 8 1 ; 10 7 3
8 7 5 ; 11 9 ; 10 4 3 2 1
8 5 4 3 ; 11 9 ; 10 7 2 1
7 5 4 3 1 ; 11 9 ; 10 8 2
Parmi ces possibilités, bien que 10 9 1 ait
l’enchevêtrement quantique le plus faible (90), la configuration avec
seulement deux colis, 11 9, dans le sac à dos est celle qui
l’emporte. Dans cette situation, l’enchevêtrement quantique de la
configuration idéale est donc 99.
Écrivez la méthode itHangsInTheBalance qui renvoie
l’enchevêtrement quantique du premier groupe de colis dans la
configuration idéale.
public static long itHangsInTheBalance(Path path) throws IOException {Caractéristiques des fichiers d’entrée :
L’entrée est un fichier contenant un poids sur chaque ligne.
DIFFICULTÉ Niv. 1
Nombre de poids max: 18
DIFFICULTÉ Niv. 2
Nombre de boîtes max: 35
Source: https://adventofcode.com/2015/day/24
StreamPour chaque exercice de la premières partie, lorsque c’est possible
et si la complexité est la même (en temps et en mémoire), réécrire le
code en utilisant des Stream.