From 4be6a24fe550bf35c874430e24de7df609b7f94f Mon Sep 17 00:00:00 2001 From: Orestis <orestis.malaspinas@pm.me> Date: Tue, 12 Oct 2021 20:54:47 +0200 Subject: [PATCH] added cours_4 --- slides/cours_3.md | 356 +--------------------------------------- slides/cours_4.md | 405 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 407 insertions(+), 354 deletions(-) create mode 100644 slides/cours_4.md diff --git a/slides/cours_3.md b/slides/cours_3.md index 8e2ce66..f9e4733 100644 --- a/slides/cours_3.md +++ b/slides/cours_3.md @@ -283,6 +283,8 @@ int main() { // pseudo C } ``` +<!-- TODO: Live implémentation hors des cours? --> + # Les palindromes Mot qui se lit pareil de droite à gauche que de gauche à droite: @@ -334,358 +336,4 @@ Algorithme de génération de nombres premiers. * Implémenter l'algorithme et le poster sur le salon `Element`. -# Crible d'Ératosthène: solution - -\footnotesize - -```C -#include <stdio.h> -#include <stdbool.h> -#define SIZE 51 -int main() { - bool tab[SIZE]; - for (int i=0;i<SIZE;i++) { - tab[i] = true; - } - for (int i = 2; i < SIZE; i++) { - if (tab[i]) { - printf("%d ", i); - int j = i; - while (j < SIZE) { - j += i; - tab[j] = false; - } - } - } - printf("\n"); -} -``` - -# Tableau à deux dimensions (1/4) - -## Mais qu'est-ce donc? - -. . . - -* Un tableau où chaque cellule est un tableau. - -## Quels cas d'utilisation? - -. . . - -* Tableau à double entrée; -* Image; -* Écran (pixels); -* Matrice (mathématique); - -# Tableau à deux dimensions (2/4) - -## Exemple: tableau à 3 lignes et 4 colonnes d'entiers - -+-----------+-----+-----+-----+-----+ -| `indices` | `0` | `1` | `2` | `3` | -+-----------+-----+-----+-----+-----+ -| `0` | `7` | `4` | `7` | `3` | -+-----------+-----+-----+-----+-----+ -| `1` | `2` | `2` | `9` | `2` | -+-----------+-----+-----+-----+-----+ -| `2` | `4` | `8` | `8` | `9` | -+-----------+-----+-----+-----+-----+ - -## Syntaxe - -```C -int tab[3][4]; // déclaration d'un tableau 4x3 -tab[2][1]; // accès à la case 2, 1 -tab[2][1] = 14; // assignation de 14 à la position 2, 1 -``` - -# Tableau à deux dimensions (3/4) - -## Exercice: déclarer et initialiser aléatoirement un tableau `50x100` - -. . . - -```C -#define NX 50 -#define NY 100 -int tab[NX][NY]; -for (int i = 0; i < NX; ++i) { - for (int j = 0; j < NY; ++j) { - tab[i][j] = rand() % 256; // 256 niveaux de gris - } -} -``` - -## Exercice: afficher le tableau - -. . . - -```C -for (int i = 0; i < NX; ++i) { - for (int j = 0; j < NY; ++j) { - printf("%d ", tab[i][j]); - } - printf("\n"); -} -``` - -# Tableau à deux dimensions (4/4) - -## Attention - -* Les éléments ne sont **jamais** initialisés. -* Les bornes ne sont **jamais** vérifiées. - - ```C - int tab[3][2] = { {1, 2}, {3, 4}, {5, 6} }; - printf("%d\n", tab[2][1]); // affiche? - printf("%d\n", tab[10][9]); // affiche? - printf("%d\n", tab[3][1]); // affiche? - ``` - -# La couverture de la reine - -* Aux échecs la reine peut se déplacer horizontalement et verticalement -* Pour un échiquier `5x6`, elle *couvre* les cases comme ci-dessous - -+-----+-----+-----+-----+-----+-----+-----+ -| ` ` | `0` | `1` | `2` | `3` | `4` | `5` | -+-----+-----+-----+-----+-----+-----+-----+ -| `0` | `*` | ` ` | `*` | ` ` | `*` | ` ` | -+-----+-----+-----+-----+-----+-----+-----+ -| `1` | ` ` | `*` | `*` | `*` | ` ` | ` ` | -+-----+-----+-----+-----+-----+-----+-----+ -| `2` | `*` | `*` | `R` | `*` | `*` | `*` | -+-----+-----+-----+-----+-----+-----+-----+ -| `3` | ` ` | `*` | `*` | `*` | ` ` | ` ` | -+-----+-----+-----+-----+-----+-----+-----+ -| `4` | `*` | ` ` | `*` | ` ` | `*` | ` ` | -+-----+-----+-----+-----+-----+-----+-----+ - -## Exercice - -* En utilisant les conditions, les tableaux à deux dimensions, et des - `char` uniquement. -* Implémenter un programme qui demande à l'utilisateur d'entrer les - coordonnées de la reine et affiche un tableau comme ci-dessus pour un - échiquier `8x8`. - -## Poster le résultat sur `Element` - -# Représentation des nombres (1/2) - -* Le nombre `247`. - -## Nombres décimaux: Les nombres en base 10 - -+--------+--------+--------+ -| $10^2$ | $10^1$ | $10^0$ | -+--------+--------+--------+ -| `2` | `4` | `7` | -+--------+--------+--------+ - -$$ -247 = 2\cdot 10^2 + 4\cdot 10^1 + 7\cdot 10^0. -$$ - -# Représentation des nombres (2/2) - -* Le nombre `11110111`. - -## Nombres binaires: Les nombres en base 2 - -+-------+-------+-------+-------+-------+-------+-------+-------+ -| $2^7$ | $2^6$ | $2^5$ | $2^4$ | $2^3$ | $2^2$ | $2^1$ | $2^0$ | -+-------+-------+-------+-------+-------+-------+-------+-------+ -| `1` | `1` | `1` | `1` | `0` | `1` | `1` | `1` | -+-------+-------+-------+-------+-------+-------+-------+-------+ - -$$ -1\cdot 2^7 + 1\cdot 2^6 +1\cdot 2^5 +1\cdot 2^4 +0\cdot 2^3 +1\cdot 2^2 -+1\cdot 2^1 +1\cdot 2^0 -$$ - -. . . - -$$ -= 247. -$$ - -# Conversion de décimal à binaire (1/N) - -## Convertir 11 en binaire? - -. . . - -* On décompose en puissances de 2 en partant de la plus grande possible - - ``` - 11 / 8 = 1, 11 % 8 = 3 - 3 / 4 = 0, 3 % 4 = 3 - 3 / 2 = 1, 3 % 2 = 1 - 1 / 1 = 1, 1 % 1 = 0 - ``` -* On a donc - - $$ - 1011 \Rightarrow 1\cdot 2^3 + 0\cdot 2^2 + 1\cdot 2^1 + 1\cdot - 2^0=11. - $$ - -# Conversion de décimal à binaire (2/N) - -## Convertir un nombre arbitraire en binaire: 247? - -* Par groupe établir un algorithme. - -. . . - -## Algorithme - -1. Initialisation - - ```C - num = 247 - while (2^N < num) { - N += 1 - } - ``` -. . . - -2. Boucle - - ```C - while (N >= 0) { - bit = num / 2^N - num = num % 2^N - N += 1 - } - ``` - - -# TODO - -## Entiers, entiers non-signés - -## Complément à 1, 2 - -## Nombres à virgule flottante, simple/double précision - -# Types composés: `struct`{.C} (1/6) - -## Fractions - -* Plusieurs variables qu'on aimerait regrouper dans un seul type: `struct`{.C}. -* Numérateur: `int num`; -* Dénominateur: `int denom`. - -## Addition - -```C -int num1 = 1, denom1 = 2; -int num2 = 1, denom2 = 3; -int num3 = num1 * denom2 + num2 * denom1; -int denom3 = denom1 * denom2; -``` - -## Pas super pratique.... - -# Types composés: `struct`{.C} (2/6) - -## On peut faire mieux - -```C -struct fraction { // déclaration du type - int32_t num, denom; -} - -struct fraction frac; // déclaration de frac -``` - -# Types composés: `struct`{.C} (3/6) - -## Simplifications - -- `typedef`{.C} permet de définir un nouveau type. - - ```C - typedef unsinged int uint; - typedef struct fraction fraction_t; - typedef struct fraction { - int32_t num, denom; - } fraction_t; - ``` -- L'initialisation peut aussi se faire avec - - ```C - fraction_t frac = {1, -2}; // num = 1, denom = -2 - fraction_t frac = {.denom = 1, .num = -2}; - fraction_t frac = {.denom = 1}; // argl! .num non initialisé - fraction_t frac2 = frac; // copie - ``` - -# Types composés: `struct`{.C} (4/6) - -## Pointeurs - -- Comme pour tout type, on peut avoir des pointeurs vers un `struct`{.C}. -- Les champs sont accessible avec le sélecteur `->`{.C} - - ```C - fraction_t *frac; // on crée un pointeur - frac->num = 1; // seg fault... - frac->denom = -1; // mémoire pas allouée. - ``` - -{width=50%} - -# Types composés: `struct`{.C} (5/6) - -## Initialisation - -- Avec le passage par **référence** on peut modifier un struct *en place*. -- Les champs sont accessible avec le sélecteur `->`{.C} - - ```C - void fraction_init(fraction_t *frac, - int32_t re, int32_t im) - { - // frac a déjà été allouée - frac->num = frac; - frac->denom = denom; - } - int main() { - fraction_t frac; // on alloue une fraction - fraction_init(&frac, 2, -1); // on l'initialise - } - ``` - -# Types composés: `struct`{.C} (6/6) - -## Initialisation version copie - -* On peut allouer une fraction, l'initialiser et le retourner. -* La valeur retournée peut être copiée dans une nouvelle structure. - - ```C - fraction_t fraction_create(int32_t re, int32_t im) { - fraction_t frac; - frac.num = re; - frac.denom = im; - return frac; - } - int main() { - // on crée une fraction et on l'initialise - // en copiant la fraction créé par fraction_create - // deux allocation et une copie - fraction_t frac = fraction_create(2, -1); - } - ``` - -# TODO jusqu'aux vacances -* Refactorisation -* Tris et complexité -* Récursivité diff --git a/slides/cours_4.md b/slides/cours_4.md new file mode 100644 index 0000000..93c493c --- /dev/null +++ b/slides/cours_4.md @@ -0,0 +1,405 @@ +--- +title: "Introduction aux algorithmes" +date: "2021-10-13" +patat: + eval: + tai: + command: fish + fragment: false + replace: true + ccc: + command: fish + fragment: false + replace: true + images: + backend: auto +... + +# Crible d'Ératosthène: solution + +\footnotesize + +```C +#include <stdio.h> +#include <stdbool.h> +#define SIZE 51 +int main() { + bool tab[SIZE]; + for (int i=0;i<SIZE;i++) { + tab[i] = true; + } + for (int i = 2; i < SIZE; i++) { + if (tab[i]) { + printf("%d ", i); + int j = i; + while (j < SIZE) { + j += i; + tab[j] = false; + } + } + } + printf("\n"); +} +``` + + +# Réusinage de code (refactoring) + +## Le réusinage est? + +. . . + +* le processus de restructuration d'un programme: + * en modifiant son design, + * en modifiant sa structure, + * en modifiant ses algorithmes + * mais en **conservant ses fonctionalités**. + +. . . + +## Avantages? + +. . . + +* Amélioration de la lisibilité, +* Amélioration de la maintenabilité, +* Réduction de la complexité. + +. . . + +## "Make it work, make it nice, make it fast", Kent Beck. + +. . . + +## Exercice: + +* Réusiner le code se trouvant sur [Cyberlearn]() + +# Tableau à deux dimensions (1/4) + +## Mais qu'est-ce donc? + +. . . + +* Un tableau où chaque cellule est un tableau. + +## Quels cas d'utilisation? + +. . . + +* Tableau à double entrée; +* Image; +* Écran (pixels); +* Matrice (mathématique); + +# Tableau à deux dimensions (2/4) + +## Exemple: tableau à 3 lignes et 4 colonnes d'entiers + ++-----------+-----+-----+-----+-----+ +| `indices` | `0` | `1` | `2` | `3` | ++-----------+-----+-----+-----+-----+ +| `0` | `7` | `4` | `7` | `3` | ++-----------+-----+-----+-----+-----+ +| `1` | `2` | `2` | `9` | `2` | ++-----------+-----+-----+-----+-----+ +| `2` | `4` | `8` | `8` | `9` | ++-----------+-----+-----+-----+-----+ + +## Syntaxe + +```C +int tab[3][4]; // déclaration d'un tableau 4x3 +tab[2][1]; // accès à la case 2, 1 +tab[2][1] = 14; // assignation de 14 à la position 2, 1 +``` + +# Tableau à deux dimensions (3/4) + +## Exercice: déclarer et initialiser aléatoirement un tableau `50x100` + +. . . + +```C +#define NX 50 +#define NY 100 +int tab[NX][NY]; +for (int i = 0; i < NX; ++i) { + for (int j = 0; j < NY; ++j) { + tab[i][j] = rand() % 256; // 256 niveaux de gris + } +} +``` + +## Exercice: afficher le tableau + +. . . + +```C +for (int i = 0; i < NX; ++i) { + for (int j = 0; j < NY; ++j) { + printf("%d ", tab[i][j]); + } + printf("\n"); +} +``` + +# Tableau à deux dimensions (4/4) + +## Attention + +* Les éléments ne sont **jamais** initialisés. +* Les bornes ne sont **jamais** vérifiées. + + ```C + int tab[3][2] = { {1, 2}, {3, 4}, {5, 6} }; + printf("%d\n", tab[2][1]); // affiche? + printf("%d\n", tab[10][9]); // affiche? + printf("%d\n", tab[3][1]); // affiche? + ``` + +# La couverture de la reine + +* Aux échecs la reine peut se déplacer horizontalement et verticalement +* Pour un échiquier `5x6`, elle *couvre* les cases comme ci-dessous + ++-----+-----+-----+-----+-----+-----+-----+ +| ` ` | `0` | `1` | `2` | `3` | `4` | `5` | ++-----+-----+-----+-----+-----+-----+-----+ +| `0` | `*` | ` ` | `*` | ` ` | `*` | ` ` | ++-----+-----+-----+-----+-----+-----+-----+ +| `1` | ` ` | `*` | `*` | `*` | ` ` | ` ` | ++-----+-----+-----+-----+-----+-----+-----+ +| `2` | `*` | `*` | `R` | `*` | `*` | `*` | ++-----+-----+-----+-----+-----+-----+-----+ +| `3` | ` ` | `*` | `*` | `*` | ` ` | ` ` | ++-----+-----+-----+-----+-----+-----+-----+ +| `4` | `*` | ` ` | `*` | ` ` | `*` | ` ` | ++-----+-----+-----+-----+-----+-----+-----+ + +## Exercice + +* En utilisant les conditions, les tableaux à deux dimensions, et des + `char` uniquement. +* Implémenter un programme qui demande à l'utilisateur d'entrer les + coordonnées de la reine et affiche un tableau comme ci-dessus pour un + échiquier `8x8`. + +## Poster le résultat sur `Element` + +# Représentation des nombres (1/2) + +* Le nombre `247`. + +## Nombres décimaux: Les nombres en base 10 + ++--------+--------+--------+ +| $10^2$ | $10^1$ | $10^0$ | ++--------+--------+--------+ +| `2` | `4` | `7` | ++--------+--------+--------+ + +$$ +247 = 2\cdot 10^2 + 4\cdot 10^1 + 7\cdot 10^0. +$$ + +# Représentation des nombres (2/2) + +* Le nombre `11110111`. + +## Nombres binaires: Les nombres en base 2 + ++-------+-------+-------+-------+-------+-------+-------+-------+ +| $2^7$ | $2^6$ | $2^5$ | $2^4$ | $2^3$ | $2^2$ | $2^1$ | $2^0$ | ++-------+-------+-------+-------+-------+-------+-------+-------+ +| `1` | `1` | `1` | `1` | `0` | `1` | `1` | `1` | ++-------+-------+-------+-------+-------+-------+-------+-------+ + +$$ +1\cdot 2^7 + 1\cdot 2^6 +1\cdot 2^5 +1\cdot 2^4 +0\cdot 2^3 +1\cdot 2^2 ++1\cdot 2^1 +1\cdot 2^0 +$$ + +. . . + +$$ += 247. +$$ + +# Conversion de décimal à binaire (1/N) + +## Convertir 11 en binaire? + +. . . + +* On décompose en puissances de 2 en partant de la plus grande possible + + ``` + 11 / 8 = 1, 11 % 8 = 3 + 3 / 4 = 0, 3 % 4 = 3 + 3 / 2 = 1, 3 % 2 = 1 + 1 / 1 = 1, 1 % 1 = 0 + ``` +* On a donc + + $$ + 1011 \Rightarrow 1\cdot 2^3 + 0\cdot 2^2 + 1\cdot 2^1 + 1\cdot + 2^0=11. + $$ + +# Conversion de décimal à binaire (2/N) + +## Convertir un nombre arbitraire en binaire: 247? + +* Par groupe établir un algorithme. + +. . . + +## Algorithme + +1. Initialisation + + ```C + num = 247 + while (2^N < num) { + N += 1 + } + ``` +. . . + +2. Boucle + + ```C + while (N >= 0) { + bit = num / 2^N + num = num % 2^N + N += 1 + } + ``` + + +# TODO + +## Entiers, entiers non-signés + +## Complément à 1, 2 + +## Nombres à virgule flottante, simple/double précision + +# Types composés: `struct`{.C} (1/6) + +## Fractions + +* Plusieurs variables qu'on aimerait regrouper dans un seul type: `struct`{.C}. +* Numérateur: `int num`; +* Dénominateur: `int denom`. + +## Addition + +```C +int num1 = 1, denom1 = 2; +int num2 = 1, denom2 = 3; +int num3 = num1 * denom2 + num2 * denom1; +int denom3 = denom1 * denom2; +``` + +## Pas super pratique.... + +# Types composés: `struct`{.C} (2/6) + +## On peut faire mieux + +```C +struct fraction { // déclaration du type + int32_t num, denom; +} + +struct fraction frac; // déclaration de frac +``` + +# Types composés: `struct`{.C} (3/6) + +## Simplifications + +- `typedef`{.C} permet de définir un nouveau type. + + ```C + typedef unsinged int uint; + typedef struct fraction fraction_t; + typedef struct fraction { + int32_t num, denom; + } fraction_t; + ``` +- L'initialisation peut aussi se faire avec + + ```C + fraction_t frac = {1, -2}; // num = 1, denom = -2 + fraction_t frac = {.denom = 1, .num = -2}; + fraction_t frac = {.denom = 1}; // argl! .num non initialisé + fraction_t frac2 = frac; // copie + ``` + +# Types composés: `struct`{.C} (4/6) + +## Pointeurs + +- Comme pour tout type, on peut avoir des pointeurs vers un `struct`{.C}. +- Les champs sont accessible avec le sélecteur `->`{.C} + + ```C + fraction_t *frac; // on crée un pointeur + frac->num = 1; // seg fault... + frac->denom = -1; // mémoire pas allouée. + ``` + +{width=50%} + +# Types composés: `struct`{.C} (5/6) + +## Initialisation + +- Avec le passage par **référence** on peut modifier un struct *en place*. +- Les champs sont accessible avec le sélecteur `->`{.C} + + ```C + void fraction_init(fraction_t *frac, + int32_t re, int32_t im) + { + // frac a déjà été allouée + frac->num = frac; + frac->denom = denom; + } + int main() { + fraction_t frac; // on alloue une fraction + fraction_init(&frac, 2, -1); // on l'initialise + } + ``` + +# Types composés: `struct`{.C} (6/6) + +## Initialisation version copie + +* On peut allouer une fraction, l'initialiser et le retourner. +* La valeur retournée peut être copiée dans une nouvelle structure. + + ```C + fraction_t fraction_create(int32_t re, int32_t im) { + fraction_t frac; + frac.num = re; + frac.denom = im; + return frac; + } + int main() { + // on crée une fraction et on l'initialise + // en copiant la fraction créé par fraction_create + // deux allocation et une copie + fraction_t frac = fraction_create(2, -1); + } + ``` + +# TODO jusqu'aux vacances + +* Refactorisation +* Tris et complexité +* Récursivité -- GitLab