Objectif : Lire et Analyser un sujet - Choisir les bonnes structures de données pour des problèmes simples - Analyser les besoins en temps et en mémoire.
Pour tous les exercices de cette session, on vous fournit un fichier
squelette Session2.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 Session2Test.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.

Un groupe de lémuriens cherche à traverser une rivière en passant sur une corde tendue entre les deux rives. La corde a une longueur fixe N > 0, et l’on considère qu’il y a N positions différentes sur la corde, numérotées de 0 à N − 1. La corde peut accueillir au plus N lémuriens en même temps, chacun à une position distincte (il ne peut pas y avoir deux lémuriens à la même position). Un lémurien peut avancer d’une seule position à la fois sur la corde, et seulement à condition qu’il n’y ait pas de lémurien juste devant lui. Tous les lémuriens avancent dans le même sens. Lorsqu’un lémurien entre sur la corde, il occupe la position 0 et, lorsqu’il se trouve à la dernière position et qu’il avance, il sort de la corde et se retrouve sur l’autre rive. Comme il s’agit d’une rivière magique, dès que le lémurien touche la rive après avoir traversé sur la corde, il est téléporté instantanément sur l’autre rive (celle de départ), et peut à nouveau tenter de traverser.
Beaucoup de lémuriens cherchent à traverser en même temps, et le
processus semble désorganisé, mais vous remarquez que les lémuriens
communiquent : à chaque fois que l’un d’entre eux souhaite avancer (ou
entrer sur la corde), il crie son nom. Afin d’étudier le processus, vous
enregistrez les noms criés par les lémuriens pendant quelques heures et
vous les transcrivez dans un fichier (votre entrée). Au moment
d’analyser vos données, vous réalisez que vous avez oublié de compter
combien de lémuriens ont réussi à effectuer une traversée complète. Ce
n’est pas très grave, vous pensez pouvoir écrire un programme permettant
de retrouver le compte. Écrivez la fonction lemurs
correspondante.
public static int lemurs(Path path) throws IOExceptionCaractéristiques des fichiers d’entrée:
L’entrée est un fichier contenant sur la première ligne, la longueur N de la corde, et ensuite un nom de lémurien par ligne.
DIFFICULTÉ Niv. 1
Taille de la corde max: 100
Nombre de lignes max: 100_000
Nombre de lémuriens différents max: 10
DIFFICULTÉ Niv. 2
Taille de la corde max: 100_000
Nombre de lignes max: 100_000_000
Nombre de lémuriens différents max: 100
Exemple :
3 --> taille de la corde
A --> A rentre sur la corde (0)
B --> B ne peut pas rentrer (la position 0 est occupée par A)
A --> A avance (1)
C --> C rentre sur la corde (0)
B --> B ne peut pas rentrer
A --> A avance (2)
A --> A sort (et se retrouve à nouveau sur la rive de départ)
C --> C avance (1)
A --> A rentre sur la corde (0)
C --> C avance (2)
A --> A avance (1)
B --> B rentre sur la corde (0)
C --> C sort, valeur de sortie: 2

Les souris qui vivent dans votre immeuble font des provisions pour l’hiver en stockant du fromage dans une boîte. La boîte a une taille fixe N > 0, et les souris peuvent stocker au maximum N morceaux de fromage en même temps. Quand une souris ajoute un morceau de fromage, elle le dépose au fond de la boîte, après tous les autres, avec une petite étiquette à son nom.Lorsqu’une souris a un petit creux, elle vient prendre le premier fromage de la boîte, quelle que soit l’étiquette qu’il porte. Si la boîte est vide, la souris repart sans fromage.
Quand une souris arrive pour déposer un morceau de fromage, si la boîte est pleine, elle doit attendre que la boîte se vide un peu pour le déposer. Comme les souris sont très bien organisées, elles ont décidé de nommer un contrôleur de la file d’attente pour déposer les fromages. La dépose s’effectue dans un ordre dicté par une note (entre 1 et une valeur max K) attribuée à chaque souris quand elle arrive devant la boîte. La souris en attente ayant la plus haute note sera celle qui pourra déposer son fromage en premier. Et si deux souris ont la même note, c’est celle qui est arrivée le plus tôt qui peut déposer. Afin de vérifier que son système fonctionne bien, le contrôleur note toutes les actions des souris dans son carnet (votre entrée) : le nom de chaque souris quand elle arrive pour déposer un fromage, ainsi que la note qu’on lui a attribuée, et aussi tous les moments où une souris prend un fromage. Il remarque au passage que certaines souris essaient de tricher en revenant avec une autre note alors qu’elles sont déjà en attente. Dans ce cas, il les gronde un peu et ne tient pas compte de leur nouvelle demande.
Le contrôleur a du mal à tout gérer tout seul et il décide de prendre
un apprenti (vous). Pour vérifier que vous avez bien compris son
système, il vous donne ses notes et vous demande d’écrire la liste des
étiquettes des fromages qui ont été retirés de la boîte, dans l’ordre.
Écrivez la fonction mice correspondante.
public static List<String> mice(Path path) throws IOExceptionCaractéristiques des fichiers d’entrée:
L’entrée est un fichier contenant sur la première ligne la taille N de la boîte, et ensuite sur chaque ligne, soit un nom de souris suivi de sa note (séparés par un espace), soit le caractère # pour indiquer qu’une souris essaie de prendre un fromage.
DIFFICULTÉ Niv. 1
Taille de la boite max: 10
Nombre de lignes max: 10_000
Nombre de souris différentes max: 500
Note max: 50
DIFFICULTÉ Niv. 2
Taille de la boite max: 20
Nombre de lignes max: 10_000_000
Nombre de souris différentes max: 10_000_000
Note max: 50
DIFFICULTÉ Niv. 3
Taille de la boite max: 20
Nombre de lignes max: 10_000_000
Nombre de souris différentes max: 10_000_000
Note max: Integer.MAX_VALUE
Exemple :
3
Pippin 2
Squeak 3
#
Nibbles 1
Nibbles 3
Whiskers 2
#
Nibbles 2
#
Whiskers 1
#
#
Squeak 2
Nibbles 3
#
Squeak 1
# --> [Pippin, Squeak, Nibbles, Nibbles, Whiskers, Nibbles, Whiskers]

Pour vous détendre après une longue journée de cours, vous aimez bien
faire la grille de mots mêlés du journal : il s’agit de trouver tous les
mots d’une liste donnée dans une grille de lettres. Dans cette grille,
les mots peuvent être écrits horizontalement, verticalement, en
diagonale, à l’envers, et ils peuvent même se chevaucher avec d’autres
occurrences. Quand vous ouvrez le journal d’aujourd’hui, une surprise
vous attend… Un petit malin a remplacé tous les mots de la liste par un
unique mot : FROG, et vous devez compter toutes les occurrences de FROG
dans la grille du journal (votre entrée). Vous n’avez aucune envie de
faire cela à la main, vous dégainez votre clavier et vous écrivez une
fonction frogs pour résoudre le problème.
public static int frogs(Path path) throws IOExceptionCaractéristiques des fichiers d’entrée:
L’entrée est un fichier contenant la grille de caractères.
Taille max de la grille: 10_000 x 5_000
Exemple :
GFFROG
OFG?G?
GGROGO
GOG?RO
GGRG?F
OGGF?O --> 3
RRRGFFROGR
RGORFRGRGO
ORFGFROORR
RGOROGRGRF
FROGORFORR
FFORRFFORO
GRGRGOGFGG
GOFOROGOOO
RORRRFRRRR
RFRFOFROGF --> 18
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.