diff --git a/Makefile b/Makefile
index 05189ad57601a6ccd7781a3f0ccd282b1d6e7499..4a1f9edba3c3dbd9a16fca4f25058030b849438c 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ read: ${PDF}
 	firefox $^
 
 %.pdf: %.md Makefile
-	pandoc --pdf-engine=xelatex -o $@ $<
+	pandoc --pdf-engine=xelatex -N -o $@ $<
 
 clean:
 	rm -rf ${PDF}
diff --git a/img/kmeans_clustering.png b/img/kmeans_clustering.png
new file mode 100644
index 0000000000000000000000000000000000000000..7fdf5934d45a27f0c750ede8ecdc40601012f78b
Binary files /dev/null and b/img/kmeans_clustering.png differ
diff --git a/kmeans.md b/kmeans.md
deleted file mode 100644
index c8e060536456b05bae78cecb48f1edd4292478f7..0000000000000000000000000000000000000000
--- a/kmeans.md
+++ /dev/null
@@ -1,168 +0,0 @@
----
-title: Programmation séquentielle - K-Means
-author:
-- GENGA Dario
-- JAQUET Steven
-- MAYA Inès
-- ROSSMANN Théo
-- STEFANOVIC Boris
-date: 2022-05-10
-geometry: "margin=40mm"
-mainfont: DejaVu Sans
-header-includes:
-- \usepackage{float}
-- \let\origfigure\figure
-- \let\endorigfigure\endfigure
-- \renewenvironment{figure}[1][2] {\expandafter\origfigure\expandafter[H]} {\endorigfigure}
----
-
-# Buts
-- Le but de ce travail pratique est d'implémenter la méthode des k-moyennes pour
-partitionner des données de façon non supervisée.
-
-# Le partitionnement de données
-De façon générale, le partitionnement de données consiste à grouper des données
-en clusters de façon à ce que les éléments d'un même groupe soient proches les
-uns des autres ou d'un élément virtuel représentant l'élément "moyen" de la
-partition.
-
-# Méthodes des k-moyennes
-Dans ce travail vous devrez implémenter l'algorithme k-moyennes (k-means en anglais)
-qui permet de partionner un groupe de données par rapport à une metrique définie.
-Ce processus de regroupement de données s'effectue de manière non-supervisée, c'est-à-dire que l'algorithme utilisé s'applique sur des données non-étiquetées
-et sans avoir recours à un retour externe sur ses résultats.
-
-
-# Énoncé
-À partir d'un fichier contenant des points à 2 dimensions, implémenter l'algorithme k-moyennes et visualiser les différents clusters créés.
-
-## Fonction distance
-Afin de quantifier la proximité de deux éléments entre eux, nous avons
-besoin de définir une fonction distance, qui sera notre métrique.
-
-Cette fonction distance peut être aussi simple qu'une distance
-de Manhattan ou une distance euclidienne, par exemple.
-
-Cette fonction prend en argument deux vecteurs éléments de notre univers.
-
-$$d(x,y)$$
-
-Une grande valeur de retour indiquera que $x$ et $y$ sont éloignés.
-Inversément, une petite valeur de retour indiquera qu'ils sont proches.
-
-## Distance euclidienne
-- calculer la distance entre un point a l'aide de la dst euclidienne et les centroides : sqrt((x2-x1)^2 + (y2-y1)^2) = sqrt((x-y)^2)
-- comparer les dst qui séparent le point aux centroides
-- assigner le point au centroide le plus proche
-- faire ca pour tous les points
-
-## Distance de Manhattan
-- calculer la distance entre un point a l'aide de la dst euclidienne et les centroides : |(x2 - x1)| + |(y2-y1)|
-- comparer les dst qui séparent le point aux centroides
-- assigner le point au centroide le plus proche
-- faire ca pour tous les points
-
-
-## Fonctions à implémenter
-Votre programme doit implémenter les fonctions suivantes :
-- Définir _k_ centroide aleatoirement
-- Calculer la distance euclidienne entre le centre d'un centroide et d'un point
-- Calculer la nouvelle position d'un centroide (à partir de la moyenne des points)
-- Lire un fichier contenant des points
-- Déterminer les points appartenant aux closters
-- Déterminer le K optimal (Elbow optimal, silhouette method, ...)
-
-Ainsi que les structures ci-dessous :
-
-```c
-typedef struct _cluster {
-    point* centroid;
-    int color;
-} cluster;
-
-typedef struct _point {
-    float x;
-    float y;
-    char* label; // for tests
-    struct _cluster* cluster;
-    int color;
-} point;
-
-
-typedef struct _kmeans {
-    int k;
-    cluster clusters_array[k];
-    point** points_array;
-} kmeans;
-```
-
-### centroides
-- placer des centroides aléatoirement
-- définir quels points appartient a quel centroide
-- faire la moyenne de points qui sont egroupés à ce centroide
-- changer les cordonnées des centroides
-- répeter les actions jusqu'à que les cordonnées du centroides ne change pas
-
-
-## Type de données
-
-Cet algorithme peut s'appliquer facilement à tous types de données
-pouvant être représentées sous forme de vecteurs de valeurs.
-Cependant, nous avons décidé de limiter nos tests aux vecteurs à valeurs
-naturelles, en 2 dimensions, pour en simplifier la visualisation
-et la vérification de notre algorithme.
-
-$$v \in \mathbb{N}^2$$
-
-# Bonus
-
-**BONUS 1** : étendre l'implémentation pour pouvoir utiliser des vecteurs
-à $n$ dimensions avec $n$ passé en paramètre au début de la procédure.
-
-**BONUS 2** : implémentation de l'algorithme PCA pour la visualisation
-de vecteurs à plus de 2 dimensions.
-
-
-## Interface utilisateur
-
-Le programme fonctionnera entièrement en ligne de commande, avec possibilité
-de spécifier un fichier d'entrée. A cette fin nous utiliserons des appels à
-fscanf(...) et la lecture des arguments en ligne de commande.
-Par défaut, le programme lira les données dans la console / sur
-l'entrée standard (permet les "pipe").
-
-# Vérification
-
-## Validation des résultats
-
-### Tester le bon choix des centres originaux
-
-Pour un univers de densité relativement homogène, il ne devrait pas
-y avoir de grand déséquilibre dans le nombre d'éléments par partition.
-
-### Tester le partitionnement
-
-Pour évaluer la justesse relative d'un résultat, pour un ensemble
-de centres donné, il suffit de mesurer la distance de chaque point
-à tous les centres.
-De ces distances-là, si la plus petite n'est pas celle au centre du
-groupe dont l'élément fait partie, il y a erreur.
-
-## Validation de l'algorithme
-
-Nous allons dans un premier temps utiliser des données générées
-artificiellement et pré-labélisées.
-Ainsi, si on se retrouve avec une correspondance exacte entre les labels
-et les groupes, le test sera considéré comme validé.
-
-Nous n'allons pas faire appel au pseudo-aléatoire dans un premier temps.
-
-# Analyse
-
-## De quoi dépend la qualité des résultats ?
-
-Par qualité, nous entendons une bonne minimisation des distances
-mentionnées plus haut.
-
-- bon choix de centres initiaux
-- nombre d'itérations suffisant
diff --git a/kmeans.pdf b/kmeans.pdf
deleted file mode 100644
index 3933476d8f7ca7b402df09fd50b29854a0412e58..0000000000000000000000000000000000000000
Binary files a/kmeans.pdf and /dev/null differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..475a063c1699685e104d0bcbfc56d2b234da583c
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,153 @@
+% Programmation séquentielle - K-Means
+
+# But
+- Le but de ce travail pratique est d'implémenter la méthode des k-moyennes pour partitionner des données de façon non supervisée.
+
+# Théorie
+## Le partitionnement de données
+De façon générale, le partitionnement de données (_clustering_) consiste à grouper des données
+en _clusters_ de façon à ce que les éléments d'un même groupe soient proches les
+uns des autres ou d'un élément virtuel représentant l'élément "moyen" de la
+partition.
+
+![kmeans clustering](./img/kmeans_clustering.png)
+
+
+## Méthodes des k-moyennes
+La méthode k-moyennes (k-means en anglais) est un algorithme qui permet de partitionner un groupe de données par rapport à une métrique définie. Chaque _cluster_ devra contenir des données homogènes. De plus tous les _cluster_ doivent également être hétérogènes les uns des autres.
+
+Ce processus de regroupement de données s'effectue de manière non supervisée, c'est-à-dire que l'algorithme utilisé s'applique sur des données non étiquetées et sans avoir recours à un retour externe sur ses résultats.
+
+## Initialisation des clusters
+Avant de pouvoir appliquer l'algorithme des k-moyennes, il faut déterminer le nombre de _clusters_ souhaité ($k$) ainsi que la position de leur _centroïde_ (point représentant le centre de chaque _cluster_).
+
+Dans un premier temps la valeur de $k$ peut être choisie arbitrairement, mais il faudra par la suite déterminer la valeur la plus optimale (nous y reviendrons plus tard).
+
+La position des _centroïdes_ sera déterminée aléatoirement mais il faut s'assurer qu'ils ne soient pas trop proches les uns des autres afin d'avoir des _clusters_ cohérents. Vous devrez déterminer une distance $\delta$ minimale séparant chaque _centroïde_ entre eux.
+
+## Calcul de la distance
+Vous travaillerez avec des points à 2 dimensions contenant des coordonnées sous la forme de nombres à virgule flotante. Ainsi vous devrez les assigner à des _clusters_ par rapport à la distance séparent les points. En effet, chaque point devra appartenir au _cluster_ dont son _centroïde_ est le plus proche.
+
+
+Afin de quantifier la proximité de deux éléments entre eux, nous avons
+besoin de définir une fonction distance, qui sera notre métrique.
+
+Cette fonction distance peut retourner simplement une distance
+de Manhattan ou une distance euclidienne et prend en argument deux vecteurs éléments de notre univers.
+
+$$d(x,y)$$
+
+Une grande valeur de retour indiquera que $x$ et $y$ sont éloignés.
+Inversement, une petite valeur de retour indiquera qu'ils sont proches.
+
+Ainsi, l'assignation de chaque point à un _cluster_ se déroule de la manière suivante :
+
+1. Calculer la distance entre le point et les _centroïdes_.
+2. Comparer les distances pour déterminer le _centroïde_ le plus proche.
+3. Assigner le point au _cluster_ du _centroïde_ le plus proche .
+
+
+### Distance euclidienne
+
+La distance euclidienne ($D_e$) entre un point $x$ et $y$ correspond à :
+$$ \vec{D_e} = \sqrt{(x_2-x_1)^2 + (y_2-y_1)^2} = \sqrt{(x-y)^2} $$
+
+
+### Distance de Manhattan
+
+La distance de Manhattan ($D_m$) entre un point $x$ et $y$ correspond à :
+$$ \vec{D_m} = |(x_2 - x_2)| + |(y_2-y_2)| $$
+
+## Déterminer le $k$ optimal
+
+Afin de tirer les meilleures conclusions du résultat de notre algorithme des k-moyennes, il faut déterminer le $k$ (nombre de _cluster_) optimal.
+
+Pour cela il existe de nombreuses méthodes, les plus connues étant :
+- La méthode du coude (Elbow Method)
+- L'analyse par silhouette (Silhouette analysis)
+
+# Énoncé
+À partir d'un fichier contenant des points à 2 dimensions (chaque coordonnées étant un nombre à virgule flotante), vous devez implémenter l'algorithme k-moyennes et permettre la visualisation des différents clusters créés.
+
+Cet algorithme peut s'appliquer facilement à tous types de données
+pouvant être représentées sous forme de vecteurs de valeurs.
+Cependant, nous avons décidé de limiter ce travail aux vecteurs à valeurs
+décimales, en 2 dimensions, pour en simplifier la visualisation
+et la vérification de notre algorithme.
+
+## Interface utilisateur
+
+Le programme fonctionnera entièrement en ligne de commande, avec possibilité
+de spécifier un fichier d'entrée. À cette fin nous utiliserons des appels à
+fscanf(...) et la lecture des arguments en ligne de commande.
+Par défaut, le programme lira les données dans la console / sur
+l'entrée standard (permet les "pipe").
+
+## Déroulement de l'algorithme
+
+Une fois nos données correctement chargées, il faudra appliquer l'algorithme des k-moyennes à ces dernières :
+
+0. Déterminer le $k$.
+1. Placer $k$ _centroïdes_ aléatoirement, appartenant chacun à un _cluster_.
+2. Déterminer les points appartenant à chaque _cluster_ selon leur distance avec les _centroïdes_.
+3. Une fois tous les points (ré)assignés à un _cluster_, calculer la nouvelle position des _centroïdes_ (il s'agira du nouveau centre du _cluster_ suite à la modification des points).
+4. Recommencer à partir de l'étape 2 si la position d'au moins 1 _centroïde_ a été modifiée.
+5. Afficher les points et _clusters_ à l'écran (avec des couleurs !)
+
+Il faudra utiliser la librairie gfx pour afficher vos résultats.
+
+## Fonctions à implémenter
+Votre programme doit implémenter les fonctions suivantes :
+- Définir _k_ centroïde aléatoirement
+- Calculer la distance entre le centre d'un centroïde et d'un point
+- Calculer la nouvelle position d'un centroïde (à partir de la moyenne des points)
+- Lire un fichier contenant des points
+- Déterminer les points appartenant aux _clusters_
+- Déterminer le K optimal (Elbow optimal, silhouette method, ...)
+
+Ainsi que les structures ci-dessous :
+
+```c
+typedef struct _cluster {
+    struct _point* centroid;
+    int color;
+} cluster;
+
+typedef struct _point {
+    float x;
+    float y;
+    char* label; // for tests
+    struct _cluster* cluster;
+    int color;
+} point;
+
+typedef struct _kmeans {
+    int k;
+    struct _cluster* clusters_array; // k size
+    struct _point** points_array;
+} kmeans;
+```
+
+## Vérification du travail réalisé
+Afin de s'assurer que votre algorithme a été correctement implémenté vous devez mettre en place des fichiers de tests.
+
+Étant donné que nous utilisons un algorithme non supervisé, il est difficile de vérifier si le résultat obtenu est "correct". Néanmoins, si nous appliquons notre algorithme sur des données dont on connaît le résultat attendu, alors il est possible de s'assurer que notre implémentation est correcte. 
+
+Le fichier _data_for_tests.txt_ contient une dizaine de points directement assignés à un _cluster_. Vous devez vous assurer que votre implémentation des k-moyennes vous donne un résultat identique aux données de test.
+
+# Travail à rendre
+- Le repos git contenant le code réalisé.
+- Vous devrez également présenter votre travail à l'aide d'un support (Powerpoint par exemple).
+
+# Travail suppémentaire possible
+
+## Affichage en temps réel
+
+Au lieu d'afficher directement le résultat final de votre implémentation de l'algorithme des k-moyennes, vous devez afficher chaque étape effectuée afin que l'on puisse constater comment l'assignation des points aux _clusters_ est effectuée.
+
+## Implémentation avec vecteurs à $n$ dimensions
+
+Étendre l'implémentation pour pouvoir utiliser des vecteurs
+à $n$ dimensions avec $n$ passé en paramètre au début de la procédure.
+
+Afin de pouvoir visualiser les résultats, vous devrez également implémenter l'algorithme PCA pour la visualisation de vecteurs à plus de 2 dimensions.
\ No newline at end of file
diff --git a/readme.pdf b/readme.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c3f22aa17dc3f3da7e95685e56874f0aa4052a56
Binary files /dev/null and b/readme.pdf differ