diff --git a/mphf.png b/mphf.png
new file mode 100644
index 0000000000000000000000000000000000000000..f6cc3bd47d535596ce940f235d3855d4b9765fd7
Binary files /dev/null and b/mphf.png differ
diff --git a/tp_2_miso_dict.py b/tp_2_miso_dict.py
index 98d2a0c91f569e81c4b9ba67b1cf7bf2a35c8f82..2fb1d598541f695dfe1de06bd905325116c5ef6a 100644
--- a/tp_2_miso_dict.py
+++ b/tp_2_miso_dict.py
@@ -7,10 +7,26 @@ import sys
 
 ###### PARTIE 2 ######
 
-def experiment_load_factor(load_factors):
+def experiment_load_factor(load_factors : list):
 	"""
 	Étude du facteur de charge
+	Parameters
+	----------
+	load_factors : list
+		Une liste de facteurs de charge
+	Returns
+	-------
+	lists
+		Les temps d'insertion de clefs
+		Les nombres de réallocations de mémoire
+		Les tailles de mémoire occupée par le dictionnaire pour chaque facteur de charge
 	"""
+	insertion_times = []
+	num_resizes = []
+	sizes = []
+	for factor in load_factors :
+		dictio = {}
+	# num_elements = .......... QUESTION 2 PARTIE 2
 	return [],[],[]
 
 def experiment_longest():
diff --git a/tp_2_miso_mphf.py b/tp_2_miso_mphf.py
index ebc3d3328dd4c33b1c29a5692f95b319518eb291..3aee1c40ac8708692f56e988965a85ce36f39a7f 100644
--- a/tp_2_miso_mphf.py
+++ b/tp_2_miso_mphf.py
@@ -39,42 +39,64 @@ def construction_mphf(set_kmer, n, gamma=2, nb_niveaux=3):
 	for _ in range(nb_niveaux):
 		if len(set_kmer_courant) > 0:
 			l = len(set_kmer_courant)
+			if l==0 :
+				break #Evite une division par 0
 			tableau_principal = [-1] * (gamma * l)
 			for kmer in set_kmer_courant:
-				pass # compléter
 				# hacher le k-mer (attention, hash() peut rendre des entiers signés, nous voulons des entiers positifs)
+				hachage = abs(hash(kmer))
 				# récupérer l'adresse
 				# si le tableau principal est déjà rempli à l'adresse:
 					# mettre le kmer dans collision()
-					#sinon, écrire le hash à l'adresse dans le tableau principal
-
+					# sinon, écrire le hash à l'adresse dans le tableau principal
+				adresse = hachage % (gamma * l)
+				if tableau_principal[adresse] != -1:
+					collision.add(kmer)
+				else:
+					tableau_principal[adresse] = hachage
 			tableaux.append(tableau_principal) # expliquer
+			# Chaque niveau de hachage produit un nouveau tableau de hachage.
+			# Donc on enregistre le tableau dans tableaux pour garder une trace des niveaux.
 			set_kmer_courant = collision.copy() # expliquer
+			# On hache à nouveau les k-mers qui ont causé des collisions.
 			collision = set() # expliquer
+			# On réinitialise collision pour le prochain niveau de hachage, pour pas que les valeurs dont on n'a plus besoin s'accumulent.
+			if not set_kmer_courant:  # Arrête la boucle si plus de collisions
+				break
 
 	# Construction de la MPHF
 	mphf = [] 
 	grand_tableau = []
 	for tableau in tableaux:
 		grand_tableau.extend(tableau) # expliquer
+	# Après avoir fait tous les hachages, on regroupe les tableaux finaux de hachage dans un seul tableau.
+	grand_tableau_dict = {val: i for i, val in enumerate(grand_tableau)}
 
-	rangs = []
 	max_rang = 0
 	i = 0
 	for kmer in set_kmer:
-		pass # compléter:
 		# hacher le kmer
+		hache = abs(hash(kmer))
 		# si le hash est dans le grand_tableau
 			# récupérer son index
 			# récupérer son rang (utiliser la fonction count())
 			# ajouter à la mphf [h, rang]
 			# mettre à jour max_rang
+		if hache in grand_tableau_dict :
+			index = grand_tableau_dict[hache]
+			rang = grand_tableau[:index].count(hache)
+			mphf.append([hache, rang])
+			max_rang = max(max_rang, rang)
 
 	for kmer in set_kmer_courant: #gestion des collisions: expliquer les 3 lignes du dessous
-		max_rang += 1
-		h = abs(hash(kmer))
-		mphf.append([h, max_rang])
-	
+		max_rang += 1 # On attribue un nouveau rang unique à chaque élément en collision.
+		h = abs(hash(kmer)) # Recalcul du hash, on veut uniquement des entiers positifs.
+		mphf.append([h, max_rang])  # On ajoute le k-mer à mphf
+		# On fait ces étapes car les collisions n'ont pas pu être placées avant,
+		#  on leur attribue un rang plus grand pour ne pas perturber l'ordre précédent
+	if not mphf:
+		print("⚠️ Attention : MPHF vide, vérifiez les données en entrée.")
+
 	return mphf
 
 
@@ -98,36 +120,46 @@ def get_hash_mphf(mphf, kmer):
 	>>> 0 <= hash_mphf < n
 	True
 	"""
-	pass # TODO modifier
-
-def create_hash_table(set_kmer, n):
-    """
-    Crée une table de hachage à partir d'un ensemble de k-mers et d'une mphf
+	hache = abs(hash(kmer))
+	for h, rang in mphf :
+		if h == hache :
+			return rang
+	return -1
 
-    Parameters:
-    set_kmer (set): Ensemble de k-mers.
-    n (int): Taille de la table de hachage.
 
-    Returns:
-    list: Table de hachage créée à partir des k-mers
-    mphf: la mphf
+def create_hash_table(set_kmer, n):
+	"""
+	Crée une table de hachage à partir d'un ensemble de k-mers et d'une mphf
 
-    Examples:
-    >>> set_kmer = {'ATCG', 'TGCA', 'GCTA'}
-    >>> n = 10
-    >>> tableau = create_hash_table(set_kmer, n)
-    >>> len(tableau) == n
-    True
-    >>> all(kmer in tableau for kmer in set_kmer)
-    True
-    """
-    pass # TODO modifier
-    # créer la mphf pour les kmers
-    # initialiser un tableau de taille n (une liste)
-    # écrire les kmers aux adresses du tableau données par la mphf
-    # retourner le tableau et la mphf
+	Parameters:
+	set_kmer (set): Ensemble de k-mers.
+	n (int): Taille de la table de hachage.
 
+	Returns:
+	list: Table de hachage créée à partir des k-mers
+	mphf: la mphf
 
+	Examples:
+	>>> set_kmer = {'ATCG', 'TGCA', 'GCTA'}
+	>>> n = 10
+	>>> tableau = create_hash_table(set_kmer, n)
+	>>> len(tableau) == n
+	True
+	>>> all(kmer in tableau for kmer in set_kmer)
+	True
+	"""
+	mphf = construction_mphf(set_kmer, n)   # créer la mphf pour les kmers
+	# initialiser un tableau de taille n (une liste)
+	tableau = [None]*n
+	# écrire les kmers aux adresses du tableau données par la mphf
+	for kmer in set_kmer :
+		adresse = get_hash_mphf(mphf, kmer)
+		if adresse == -1:
+			print(f"Erreur : Impossible de trouver l'adresse pour {kmer} (MPHF renvoie -1)")
+			continue
+		if 0 <= adresse < n:
+			tableau[adresse]=kmer
+	return tableau, mphf # retourner le tableau et la mphf
 
 
 def generer_kmers(n, k):
@@ -149,10 +181,12 @@ def compare_taille(n_max, fichier_sortie):
 	
 	for n in range(100, n_max, 1000):
 		set_kmer = generer_kmers(n, k)
-		tableau, mphf = create_hash_table(set_kmer,n)
+		tableau, mphf = create_hash_table(set_kmer, n)
 
 		n_values.append(n)
-		table_size.append(sys.getsizeof(tableau)+sys.getsizeof(mphf)) # pourquoi ici on ne mesure pas juste la taille en mémoire du tableau ? 
+		table_size.append(sys.getsizeof(tableau)+sys.getsizeof(mphf)) # pourquoi ici on ne mesure pas juste la taille en mémoire du tableau ?
+		#Car sys.getsizeof(tableau) ne mesure que la liste elle-même, pas les objets stockés dedans.
+		# On veut mesurer la mémoire totale du système de hachage, pas seulement la liste.
 		dict_size.append(sys.getsizeof(set_kmer))
 
 	plt.plot(n_values, table_size, label='Table avec MPHF')
@@ -166,4 +200,10 @@ def compare_taille(n_max, fichier_sortie):
 	plt.close()
 
 # dé-commenter quand vous êtes prêts, expliquer les résultats
-#compare_taille(10000,"mphf.png")
+compare_taille(10000,"mphf.png")
+
+# Sur le graphe obtenu, on observe que la taille de la table de hachage du dictionnaire augmente par paliers,
+# alors que celle de la MPHF augmente de manière linéaire, et beaucoup plus progressivement.
+# Cela est cohérent, en effet le dictionnaire va allouer plus d'espace dès que le nombre d'éléments atteint un seuil.
+# Quant à la MPHF, elle minimise la mémoire en évitant les collisions.
+