Corrigé X-ENS 2026 Informatique A MP — Partie I (I.1 à I.10) : Reconnaissance d'extraits musicaux : vecteurs de bits, signatures, minHash
Sujet officiel du concours X-ENS, session 2026, épreuve Informatique A MP. Corrigé rédigé par Ibrahim Alame.
Sujet officiel (PDF, site du concours)
Énoncé
On note . Un spectrogramme a lignes (fréquences) et une colonne par instant ; la case vaut 'x' si la fréquence est jouée à l'instant , ' ' sinon. Sa représentation concise est la liste des cases 'x'. Figure 1 (Frère Jacques) :
type spectrogram = char array array
type sparse = (int * int) list
type signature = (int * int * int) list
Indice de Jaccard : . En I.3-I.5, une partie de est codée par un entier dont le bit vaut 1 si et seulement si est dans la partie. Pour , la signature de (durée ) est
I.1. Problème connu auquel se ramène la recherche exacte d'un extrait de durée dans une musique de durée ; complexité de la recherche naïve.
I.2. Écrire to_sparse : spectrogram -> sparse.
I.3. Écrire convert : int list -> int (liste sans doublons vers vecteur de bits).
I.4. Écrire inter : int -> int -> int (intersection).
I.5. (a) Écrire size : int -> int (cardinal), linéaire en le cardinal. (b) Correction par un invariant. Indication : b land (-b) isole le bit à 1 de plus faible poids.
I.6. (a) Écrire sparse_inter : 'a list -> 'a list -> int, nombre d'éléments communs à deux listes strictement croissantes, en temps linéaire. (b) Complexité.
I.7. (a) Écrire tosignature : sparse -> int -> signature en ( longueur de sp), via Array.of_list. (b) Complexité.
I.8. (a) Écrire signature_size : sparse -> int -> int () en un seul parcours de sp, triée par instants strictement croissants (indication : une file). Exemples : signature_size [(1, 1); (5, 5)] 3 vaut 0, signature_size [(1, 1); (2, 2); (3, 3); (4, 4); (5, 5)] 10 vaut 10. (b) Correction et complexité.
I.9. L'extrait partage trois triplets avec et trois avec , apparaissant aux instants dans , dans la musique (figure 2). Quelle musique correspond le mieux à ?
I.10. , , . (a) Pour permutation aléatoire uniforme, montrer . (b) En déduire une méthode pour trouver les musiques les plus proches d'un extrait.
Corrigé
I.1. C'est la recherche d'un motif dans un texte, sur l'alphabet des colonnes : une colonne du spectrogramme est un mot de caractères, la musique est un texte de colonnes et l'extrait un motif de colonnes. L'extrait figure dans la musique s'il existe un décalage tel que pour tous et , la case de l'extrait est égale à la case de la musique.
La recherche naïve essaie les décalages et, pour chacun, compare au plus colonnes de cases, en s'arrêtant à la première différence : au plus comparaisons, soit une complexité en , donc en . Cette borne est atteinte : une musique silencieuse (que des espaces) et un extrait silencieux sauf sa dernière case font comparer, pour chaque décalage, cases avant de trouver la différence, soit exactement comparaisons. Pour , c'est .
I.2. On parcourt toutes les cases en ajoutant en tête de liste ; en balayant les instants décroissants, la liste obtenue est triée par instants croissants (puis par fréquences croissantes), ce qui servira en I.8.
let to_sparse (s : spectrogram) : sparse =
let nf = Array.length s in
if nf = 0 then []
else begin
let nt = Array.length s.(0) in
let acc = ref [] in
for t = nt - 1 downto 0 do
for f = nf - 1 downto 0 do
if s.(f).(t) = 'x' then acc := (f, t) :: !acc
done
done;
!acc
end
Chaque case est lue une fois et produit au plus une cellule de liste : complexité . Invariant de la boucle externe : après le traitement de l'instant , !acc est la liste des cases 'x' d'instant au moins , dans l'ordre croissant. Sur la matrice de la figure 1 (en numérotant les fréquences de bas en haut, comme le clavier), la fonction renvoie [(0,0); (1,1); (2,2); (0,3); (0,4); (1,5); …; (2,14); (4,14)], 20 couples.
I.3. L'élément correspond à l'entier , c'est-à-dire 1 lsl i ; on réunit ces bits par un « ou » bit à bit.
let convert (l : int list) : int =
List.fold_left (fun acc i -> acc lor (1 lsl i)) 0 l
Par récurrence sur la longueur du préfixe déjà traité, l'accumulateur code l'ensemble des éléments de ce préfixe : acc lor (1 lsl i) met à 1 le bit sans toucher aux autres. Comme la liste est sans doublons, on pourrait aussi bien additionner les . Pour , reste un entier positif sur 63 bits. Complexité pour une liste de longueur . Exemple exécuté : convert [0; 2; 5] vaut .
I.4. Un élément est dans l'intersection si et seulement si son bit vaut 1 dans les deux codes : c'est le « et » bit à bit.
let inter (a : int) (b : int) : int = a land b
Temps constant ; par exemple inter 6 3 vaut 2 ().
I.5. (a) À chaque tour, on retire de son bit à 1 de plus faible poids, isolé par b land (-b), et l'on compte les tours.
let size (n : int) : int =
let b = ref n and c = ref 0 in
while !b <> 0 do
b := !b - (!b land (- !b));
incr c
done;
!c
Justification de l'indication. Si s'écrit en binaire (le bit est son bit à 1 de plus faible poids), le complément à deux donne , où , donc . Le « et » avec vaut . Donc b - (b land (-b)) vaut : c'est privé de son bit .
Complexité : chaque tour retire exactement un bit à 1 ; si l'ensemble codé par a éléments, la boucle fait exactement tours, chacun en (une négation, un « et », une soustraction, un test, une incrémentation). La complexité est , linéaire en la taille de l'ensemble (et non en 62, comme un parcours de tous les bits).
(b) Notons l'ensemble codé par l'entier . Invariant : et . Il est vrai à l'entrée (, ). Si avant un tour, soit : d'après (a), le tour remplace par le code de (donc reste inclus dans et perd exactement un élément) et augmente de 1 : l'invariant est conservé. Terminaison : est un entier naturel qui décroît strictement à chaque tour. À la sortie, donc et l'invariant donne : la fonction renvoie le cardinal. Vérifié sur 1000 parties aléatoires de , sur et sur tout entier (résultat 62).
100 % gratuit
La suite du corrigé est sur Adloun
Le corrigé rédigé en entier, question par question, et le tuteur pour poser des questions sur ce sujet.
Voir le corrigé complet, gratuitementInscription gratuite en 30 secondes (e-mail, nom d'utilisateur, mot de passe, classe ou profil), sans carte bancaire : arrivée directe sur le corrigé.