Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • algorithmique/cours
  • aurelien.boyer/cours
  • jeremy.meissner/cours
  • radhwan.hassine/cours
  • yassin.elhakoun/cours-algo
  • gaspard.legouic/cours
  • joachim.bach/cours
  • gabriel.marinoja/algo-cours
  • loic.lavorel/cours
  • iliya.saroukha/cours
  • costanti.volta/cours
  • jacquesw.ndoumben/cours
12 results
Select Git revision
Show changes
Commits on Source (764)
Showing
with 1439 additions and 8 deletions
*.o
*.xopp*
slides/package-lock.json
slides/package.json
slides/.vscode/settings.json
.vscode/settings.json
slides/node_modules/.package-lock.json
image: omalaspinas/pandoc:latest image: omalaspinas/c_pandoc:latest
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_STRATEGY: recursive
...@@ -9,8 +9,8 @@ before_script: ...@@ -9,8 +9,8 @@ before_script:
## Install ssh-agent if not already installed, it is required by Docker. ## Install ssh-agent if not already installed, it is required by Docker.
## (change apt-get to yum if you use an RPM-based image) ## (change apt-get to yum if you use an RPM-based image)
## ##
- 'which ssh-agent || (pacman -S --noconfirm openssh)' - 'which ssh-agent || (apk add --update openssh-client)'
- 'which rsync || (pacman -S --noconfirm rsync)' - 'which rsync || (apk add --update rsync)'
## ##
...@@ -38,8 +38,6 @@ before_script: ...@@ -38,8 +38,6 @@ before_script:
- echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts - chmod 644 ~/.ssh/known_hosts
build_only: build_only:
script: script:
- cd slides - cd slides
...@@ -47,6 +45,11 @@ build_only: ...@@ -47,6 +45,11 @@ build_only:
- make deploy - make deploy
- rsync -avz algo_cours ur1bg_malas@ur1bg.ftp.infomaniak.com:web/malaspinas/ - rsync -avz algo_cours ur1bg_malas@ur1bg.ftp.infomaniak.com:web/malaspinas/
build_examples:
script:
- cd source_codes
- make
build_artifacts: build_artifacts:
script: script:
- cd slides - cd slides
......
# Remerciements et contributions
Merci aux contributeurs suivants pour leurs efforts (dans un ordre alphabétique):
* P. Albuquerque
* J. Bach
* A. Boyer
* M. Corboz
* M. Divià
* Y. El Hakouni
* A. Escribano
* P. Kunzli
* G. Legouic
* G. Marino Jarrin
* H. Radhwan
* I. Saroukhanian
* C. Volta
*.o
main
CC=gcc
CFLAGS=-g -std=gnu11 -Wall -Wextra -pedantic -fsanitize=address -fsanitize=leak -fsanitize=undefined
LDFLAGS=-fsanitize=address -fsanitize=leak -fsanitize=undefined
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.o)
TARGET = main
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $^ -o $@ $(LDFLAGS)
hm.c: hm.h
.PHONY = clean
clean:
rm -f $(OBJECTS) $(TARGET)
#include "hm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int hash(char *key, int capacity) {
int h = 0;
for (size_t i = 0; i < strlen(key); ++i) {
h = (h + key[i] * 43) % capacity;
}
return h;
}
static int rehash(char *key) {
return 1;
}
static int find_index(hm h, char *key) {
int i = hash(key, h.capacity);
int init = i;
while (h.table[i].state != empty &&
strncmp(h.table[i].key, key, MAX_LEN) != 0) {
i = (i + rehash(key)) % h.capacity;
if (i == init) {
return -1;
}
}
return i;
}
void hm_init(hm *h, int capacity) {
h->table = malloc(capacity * sizeof(cell_t));
h->capacity = capacity;
for (int i = 0; i < h->capacity; ++i) {
h->table[i].state = empty;
}
}
void hm_destroy(hm *h) {
free(h->table);
h->table = NULL;
h->capacity = -1;
}
bool hm_set(hm *h, char *key, char *value) {
int i = hash(key, h->capacity);
int init = i;
while (h->table[i].state == occupied &&
strncmp(h->table[i].key, key, MAX_LEN) != 0) {
i = (i + rehash(key)) % h->capacity;
if (i == init) {
return false;
}
}
if (strncpy(h->table[i].key, key, MAX_LEN) == NULL) {
return false;
};
if (strncpy(h->table[i].value, value, MAX_LEN) == NULL) {
return false;
};
h->table[i].state = occupied;
return true;
}
char *hm_get(hm h, char *key) {
int i = find_index(h, key);
return (i >= 0 && h.table[i].state == occupied) ? h.table[i].value : NULL;
}
char *hm_remove(hm *h, char *key) {
int i = find_index(*h, key);
if (i >= 0 && h->table[i].state == occupied) {
h->table[i].state = deleted;
return h->table[i].value;
} else {
return NULL;
}
}
void hm_print(hm h) {
for (int i = 0; i < h.capacity; ++i) {
if (h.table[i].state == occupied) {
printf("[%d], key: %s, value: %s\n", i, h.table[i].key,
h.table[i].value);
} else {
printf("[%d], key: none, value: none\n", i);
}
}
}
#ifndef _HM_H_
#define _HM_H_
#include <stdbool.h>
#define MAX_LEN 80
typedef enum { empty, occupied, deleted } state_t;
typedef struct _cell_t {
state_t state;
char key[MAX_LEN];
char value[MAX_LEN];
} cell_t;
typedef struct _hm {
int capacity;
cell_t *table;
} hm;
void hm_init(hm *h, int capacity);
void hm_destroy(hm *h);
bool hm_set(hm *h, char *key, char *value);
char *hm_get(hm h, char *key);
char *hm_remove(hm *h, char *key);
void hm_print(hm h);
#endif
#include "hm.h"
#include <stdio.h>
int main() {
hm h;
hm_init(&h, 5);
for (int i = 0; i < 7; ++i) {
char key[MAX_LEN], value[MAX_LEN];
printf("Enter key please:\n");
scanf("%s", key);
printf("Enter value please:\n");
scanf("%s", value);
hm_set(&h, key, value);
hm_print(h);
}
printf("DELETE VALUES!\n");
for (int i = 0; i < 2; ++i) {
char key[MAX_LEN];
printf("Enter key please:\n");
scanf("%s", key);
printf("Value: ");
char *value = hm_remove(&h, key);
if (value == NULL) {
printf("Key not found.\n");
} else {
printf("Value is %s.\n", value);
}
hm_print(h);
}
printf("SEARCH VALUES!\n");
for (int i = 0; i < 2; ++i) {
char key[MAX_LEN];
printf("Enter key please:\n");
scanf("%s", key);
printf("Value: ");
char *value = hm_get(h, key);
if (value == NULL) {
printf("Key not found.\n");
} else {
printf("Value is %s.\n", value);
}
}
hm_destroy(&h);
/* for (int i = 0; i < 6; ++i) { */
/* scanf("%s", key); */
/* scanf("%s", value); */
/* } */
}
@charset "UTF-8";
/* Import ET Book styles
adapted from https://github.com/edwardtufte/et-book/blob/gh-pages/et-book.css */
@font-face {
font-family: "et-book";
src: url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.eot");
src: url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.eot?#iefix") format("embedded-opentype"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.woff") format("woff"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.ttf") format("truetype"), url("et-book/et-book-roman-line-figures/et-book-roman-line-figures.svg#etbookromanosf") format("svg");
font-weight: normal;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "et-book";
src: url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.eot");
src: url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.eot?#iefix") format("embedded-opentype"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.woff") format("woff"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.ttf") format("truetype"), url("et-book/et-book-display-italic-old-style-figures/et-book-display-italic-old-style-figures.svg#etbookromanosf") format("svg");
font-weight: normal;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: "et-book";
src: url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.eot");
src: url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.eot?#iefix") format("embedded-opentype"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.woff") format("woff"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.ttf") format("truetype"), url("et-book/et-book-bold-line-figures/et-book-bold-line-figures.svg#etbookromanosf") format("svg");
font-weight: bold;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "et-book-roman-old-style";
src: url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.eot");
src: url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.eot?#iefix") format("embedded-opentype"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.woff") format("woff"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.ttf") format("truetype"), url("et-book/et-book-roman-old-style-figures/et-book-roman-old-style-figures.svg#etbookromanosf") format("svg");
font-weight: normal;
font-style: normal;
font-display: swap;
}
/* Tufte CSS styles */
html {
font-size: 15px;
}
body {
width: 87.5%;
margin-left: auto;
margin-right: auto;
padding-left: 12.5%;
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
background-color: #fffff8;
color: #111;
max-width: 1400px;
counter-reset: sidenote-counter;
}
h1 {
font-weight: 400;
margin-top: 4rem;
margin-bottom: 1.5rem;
font-size: 3.2rem;
line-height: 1;
}
h2 {
font-style: italic;
font-weight: 400;
margin-top: 2.1rem;
margin-bottom: 1.4rem;
font-size: 2.2rem;
line-height: 1;
}
h3 {
font-style: italic;
font-weight: 400;
font-size: 1.7rem;
margin-top: 2rem;
margin-bottom: 1.4rem;
line-height: 1;
}
hr {
display: block;
height: 1px;
width: 55%;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
p.subtitle {
font-style: italic;
margin-top: 1rem;
margin-bottom: 1rem;
font-size: 1.8rem;
display: block;
line-height: 1;
}
.numeral {
font-family: et-book-roman-old-style;
}
.danger {
color: red;
}
article {
padding: 5rem 0rem;
}
section {
padding-top: 1rem;
padding-bottom: 1rem;
}
p,
dl,
ol,
ul {
font-size: 1.4rem;
line-height: 2rem;
}
p {
margin-top: 1.4rem;
margin-bottom: 1.4rem;
padding-right: 0;
vertical-align: baseline;
}
/* Chapter Epigraphs */
div.epigraph {
margin: 5em 0;
}
div.epigraph > blockquote {
margin-top: 3em;
margin-bottom: 3em;
}
div.epigraph > blockquote,
div.epigraph > blockquote > p {
font-style: italic;
}
div.epigraph > blockquote > footer {
font-style: normal;
}
div.epigraph > blockquote > footer > cite {
font-style: italic;
}
/* end chapter epigraphs styles */
blockquote {
font-size: 1.4rem;
}
blockquote p {
width: 55%;
margin-right: 40px;
}
blockquote footer {
width: 55%;
font-size: 1.1rem;
text-align: right;
}
section > p,
section > footer,
section > table {
width: 55%;
}
/* 50 + 5 == 55, to be the same width as paragraph */
section > dl,
section > ol,
section > ul {
width: 50%;
-webkit-padding-start: 5%;
}
dt:not(:first-child),
li:not(:first-child) {
margin-top: 0.25rem;
}
figure {
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
max-width: 55%;
-webkit-margin-start: 0;
-webkit-margin-end: 0;
margin: 0 0 3em 0;
}
figcaption {
float: right;
clear: right;
margin-top: 0;
margin-bottom: 0;
font-size: 1.1rem;
line-height: 1.6;
vertical-align: baseline;
position: relative;
max-width: 40%;
}
figure.fullwidth figcaption {
margin-right: 24%;
}
/* Links: replicate underline that clears descenders */
a:link,
a:visited {
color: inherit;
}
.no-tufte-underline:link {
background: unset;
text-shadow: unset;
}
a:link, .tufte-underline, .hover-tufte-underline:hover {
text-decoration: none;
background: -webkit-linear-gradient(#fffff8, #fffff8), -webkit-linear-gradient(#fffff8, #fffff8), -webkit-linear-gradient(currentColor, currentColor);
background: linear-gradient(#fffff8, #fffff8), linear-gradient(#fffff8, #fffff8), linear-gradient(currentColor, currentColor);
-webkit-background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
-moz-background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
background-size: 0.05em 1px, 0.05em 1px, 1px 1px;
background-repeat: no-repeat, no-repeat, repeat-x;
text-shadow: 0.03em 0 #fffff8, -0.03em 0 #fffff8, 0 0.03em #fffff8, 0 -0.03em #fffff8, 0.06em 0 #fffff8, -0.06em 0 #fffff8, 0.09em 0 #fffff8, -0.09em 0 #fffff8, 0.12em 0 #fffff8, -0.12em 0 #fffff8, 0.15em 0 #fffff8, -0.15em 0 #fffff8;
background-position: 0% 93%, 100% 93%, 0% 93%;
}
@media screen and (-webkit-min-device-pixel-ratio: 0) {
a:link, .tufte-underline, .hover-tufte-underline:hover {
background-position-y: 87%, 87%, 87%;
}
}
a:link::selection,
a:link::-moz-selection {
text-shadow: 0.03em 0 #b4d5fe, -0.03em 0 #b4d5fe, 0 0.03em #b4d5fe, 0 -0.03em #b4d5fe, 0.06em 0 #b4d5fe, -0.06em 0 #b4d5fe, 0.09em 0 #b4d5fe, -0.09em 0 #b4d5fe, 0.12em 0 #b4d5fe, -0.12em 0 #b4d5fe, 0.15em 0 #b4d5fe, -0.15em 0 #b4d5fe;
background: #b4d5fe;
}
/* Sidenotes, margin notes, figures, captions */
img {
max-width: 100%;
}
.sidenote,
.marginnote {
float: right;
clear: right;
margin-right: -60%;
width: 50%;
margin-top: 0.3rem;
margin-bottom: 0;
font-size: 1.1rem;
line-height: 1.3;
vertical-align: baseline;
position: relative;
}
.sidenote-number {
counter-increment: sidenote-counter;
}
.sidenote-number:after,
.sidenote:before {
font-family: et-book-roman-old-style;
position: relative;
vertical-align: baseline;
}
.sidenote-number:after {
content: counter(sidenote-counter);
font-size: 1rem;
top: -0.5rem;
left: 0.1rem;
}
.sidenote:before {
content: counter(sidenote-counter) " ";
font-size: 1rem;
top: -0.5rem;
}
blockquote .sidenote,
blockquote .marginnote {
margin-right: -82%;
min-width: 59%;
text-align: left;
}
div.fullwidth,
table.fullwidth {
width: 100%;
}
div.table-wrapper {
overflow-x: auto;
font-family: "Trebuchet MS", "Gill Sans", "Gill Sans MT", sans-serif;
}
.sans {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
letter-spacing: .03em;
}
code, pre > code {
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 1.0rem;
line-height: 1.42;
-webkit-text-size-adjust: 100%; /* Prevent adjustments of font size after orientation changes in iOS. See https://github.com/edwardtufte/tufte-css/issues/81#issuecomment-261953409 */
}
.sans > code {
font-size: 1.2rem;
}
h1 > code,
h2 > code,
h3 > code {
font-size: 0.80em;
}
.marginnote > code,
.sidenote > code {
font-size: 1rem;
}
pre > code {
font-size: 0.9rem;
width: 52.5%;
margin-left: 2.5%;
overflow-x: auto;
display: block;
}
pre.fullwidth > code {
width: 90%;
}
.fullwidth {
max-width: 90%;
clear:both;
}
span.newthought {
font-variant: small-caps;
font-size: 1.2em;
}
input.margin-toggle {
display: none;
}
label.sidenote-number {
display: inline;
}
label.margin-toggle:not(.sidenote-number) {
display: none;
}
.iframe-wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-top: 25px;
height: 0;
}
.iframe-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
@media (max-width: 760px) {
body {
width: 84%;
padding-left: 8%;
padding-right: 8%;
}
hr,
section > p,
section > footer,
section > table {
width: 100%;
}
pre > code {
width: 97%;
}
section > dl,
section > ol,
section > ul {
width: 90%;
}
figure {
max-width: 90%;
}
figcaption,
figure.fullwidth figcaption {
margin-right: 0%;
max-width: none;
}
blockquote {
margin-left: 1.5em;
margin-right: 0em;
}
blockquote p,
blockquote footer {
width: 100%;
}
label.margin-toggle:not(.sidenote-number) {
display: inline;
}
.sidenote,
.marginnote {
display: none;
}
.margin-toggle:checked + .sidenote,
.margin-toggle:checked + .marginnote {
display: block;
float: left;
left: 1rem;
clear: both;
width: 95%;
margin: 1rem 2.5%;
vertical-align: baseline;
position: relative;
}
label {
cursor: pointer;
}
div.table-wrapper,
table {
width: 85%;
}
img {
width: 100%;
}
}
main
*.o
CC=gcc
CFLAGS=-g -std=gnu11 -Wall -Wextra -pedantic -fsanitize=address -fsanitize=leak -fsanitize=undefined
LDFLAGS=-fsanitize=address -fsanitize=leak -fsanitize=undefined
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.o)
TARGET = main
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $^ -o $@ $(LDFLAGS)
hashmap.c: hashmap.h
.PHONY = clean
clean:
rm -f $(OBJECTS) $(TARGET)
#include "hm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static bool is_not_allocated(hm h) {
return (h.table == NULL || h.capacity < 1 || h.size < 0);
}
static size_t hash(hm h, char key[MAX_LEN]) {
int index = 0;
for (size_t i = 0; i < strlen(key); ++i) {
index = (index + key[i] * 43) % h.capacity;
}
return index;
}
static int rehash(char *key) {
return 1;
}
static bool search_condition(hm h, char key[MAX_LEN], int index) {
return strncmp(h.table[index].key, key, MAX_LEN) == 0 &&
h.table[index].state == occupied;
}
static bool set_condition(hm h, char key[MAX_LEN], int index) {
return search_condition(h, key, index) || h.table[index].state != occupied;
}
static int find_index(
hm h, char key[MAX_LEN], bool (*condition)(hm, char[], int)) {
int try = 0;
int index = hash(h, key);
while (try < h.capacity) {
if (condition(h, key, index)) {
return index;
}
index = (index + rehash(key)) % h.capacity;
try += 1;
}
return -1;
}
static bool is_empty(hm h) {
return h.size == 0;
}
void hm_init(hm *h, int capacity) {
h->capacity = capacity;
h->size = 0;
h->table = malloc(h->capacity * sizeof(*h->table));
for (int i = 0; i < h->capacity; ++i) {
h->table[i].state = empty;
}
}
void hm_destroy(hm *h) {
h->capacity = -1;
h->size = -1;
free(h->table);
h->table = NULL;
}
bool hm_set(hm *h, char *key, char *value) {
if (is_not_allocated(*h)) {
return false;
}
int index = find_index(*h, key, set_condition);
if (index < 0) {
return false;
}
/* printf("%d\n", index); */
strncpy(h->table[index].value, value, MAX_LEN);
strncpy(h->table[index].key, key, MAX_LEN);
h->table[index].state = occupied;
h->size += 1;
return true;
}
bool hm_get(hm h, char *key, char *value) {
int index = find_index(h, key, search_condition);
if (index >= 0) {
strncpy(value, h.table[index].value, MAX_LEN);
return true;
}
return false;
}
bool hm_remove(hm *h, char *key, char *value) {
int index = find_index(*h, key, search_condition);
if (index >= 0) {
h->table[index].state = deleted;
strncpy(value, h->table[index].value, MAX_LEN);
h->size -= 1;
return true;
}
return false;
}
bool hm_search(hm h, char *key) {
int index = find_index(h, key, search_condition);
return (index >= 0);
}
void hm_print(hm h) {
if (is_not_allocated(h)) {
printf("Well this hashmap is not allocated n00b.\n");
}
if (is_empty(h)) {
printf("The hashmap is empty.\n");
}
for (int i = 0; i < h.capacity; ++i) {
if (h.table[i].state == occupied) {
printf("index: %d, key: %s, value: %s\n", i, h.table[i].key,
h.table[i].value);
} else {
printf("index: %d, key: {none}, value: {none}\n", i);
}
}
}
#ifndef _HM_H_
#define _HM_H_
#include <stdbool.h>
#define MAX_LEN 80
typedef enum { empty, occupied, deleted } state_t;
typedef struct _cell_t {
char key[MAX_LEN];
char value[MAX_LEN];
state_t state;
} cell_t;
typedef struct _hm {
cell_t *table;
int capacity;
int size;
} hm;
void hm_init(hm *h, int capacity);
void hm_destroy(hm *h);
bool hm_set(hm *h, char *key, char *value);
bool hm_get(hm h, char *key, char *value);
bool hm_remove(hm *h, char *key, char *value);
bool hm_search(hm h, char *key);
void hm_print(hm h);
#endif
#include "hm.h"
#include <stdio.h>
int main() {
char key[80], value[80];
hm h;
hm_init(&h, 5);
for (int i = 0; i < 6; ++i) {
scanf("%s", key);
scanf("%s", value);
hm_set(&h, key, value);
hm_print(h);
if (hm_search(h, "orestis")) {
printf("orestis found.\n");
}
if (hm_remove(&h, "orestis", value)) {
printf("orestis removed: %s.\n", value);
}
}
hm_destroy(&h);
}
...@@ -15,6 +15,12 @@ void find_min(double tab[], int i0, int *ind, double *min) { ...@@ -15,6 +15,12 @@ void find_min(double tab[], int i0, int *ind, double *min) {
} }
} }
void swap(double *a, double *b) {
double tmp = *a;
*a = *b;
*b = tmp;
}
int main() { int main() {
srand(time(NULL)); srand(time(NULL));
double tab[SIZE]; double tab[SIZE];
...@@ -26,13 +32,19 @@ int main() { ...@@ -26,13 +32,19 @@ int main() {
double min = tab[i]; double min = tab[i];
int ind_min = i; int ind_min = i;
find_min(tab, i, &ind_min, &min); find_min(tab, i, &ind_min, &min);
double tmp = tab[i]; swap(&tab[i], &tab[ind_min]);
tab[i] = min;
tab[ind_min] = tmp;
} }
for (int i = 0; i < SIZE; ++i) { for (int i = 0; i < SIZE; ++i) {
printf("%f ", tab[i]); printf("%f ", tab[i]);
} }
printf("\n"); printf("\n");
for (int i = 0; i < SIZE - 1; ++i) {
if (tab[i] > tab[i + 1]) {
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
} }
*.log
*.aux
*.pdf
*.dvi
*.eps
# Algorithmes et structures de données 2020-21
Contenu du cours 1 du 16.09.2020
*****
## Présentation personnelle
[Paul Albuquerque](mailto:paul.albuquerque@hesge.ch), resp. de filière
bureau B410
022 546 2554
paul.albuquerque@hesge.ch
## Organisation du module (2 cours, 50 % chacun)
- Algorithmes et structures de données
- 1er semestre
- Bases de la programmation en C jusqu'à Noël
- Algorithmique jusque fin janvier
- 2ème semestre
- Algorithmique
> Au moins 2 évaluations par semestre
- Programmation séquentielle en langage C
- 1er & 2ème semestre :travaux pratiques en langage C
- Chaque semestre des travaux pratiques sont répartis dans deux gros projets d'env. 7 semaines
## Qu'est-ce qu'un algorithme ?
Informellement, c'est une recette ou une marche à suivre.
Plus formellement:
| Définition |
|:-----------------------------------------------------------------|
| Un **algorithme** est une suite finie et non ambiguë d'opérations|
| ou d'instructions permettant de résoudre un problème. |
Le mot *algorithme* vient du nom latinisé du mathématicien perse
[Al-Khawarizmi](http://fr.wikipedia.org/wiki/Al-Khawarizmi)
Les algorithmes des grecs : Euclide, Erastosthène
Le père de l'algorithmique : **Muhammad Ibn Mūsā al-Khuwārizmī**
Résolution d'un problème
- Décomposition en sous-problèmes
- Résolution des sous-problèmes
- Assemblage des résultats
## Notions de base d'algorithmique séquentielle
- Définition d'une variable (nom, type, valeur, adresse)
- Séquences d'instructions
- Boucles et tests (`for`, `while`, `do...while`, `if...else`)
## Algorithme de vérification qu'un nombre est 1<sup>er</sup>
- Comment demander le nombre
- Forme de l'algorithme (boucle et tests)
- Condition d'arrêt de la boucle
## Qu'est qu'un programme C ?
- Importations de librairies (paquetages) :
```C
#include <stdlio.h>
#include <stdlib.h>
```
- Entête du programme : `int main()`
- Déclaration de variables : `int x = 5;`
- Bloc d'instructions :
```C
{
int x = 5;
printf("x=%d\n",x);
}
```
## Les types de base : les entiers (`int, unsigned int`)
- Numérotation binaire en particulier sur 32 bits
- Nombres négatifs =\> complément à 2
numération sur 3 bits :
|binaire | entier&GreaterEqual;0| binaire | entier<0|
|:-------|:---------------------|:--------|:--------|
|000 | 0 | 111 | -1 |
|001 | 1 | 110 | -2 |
|010 | 2 | 101 | -3 |
|011 | 3 | 100 | -4 |
- Nombres négatifs =\> complément à 1 par simple inversion des bits
**problème **: 0 possède alors deux représentations !
- Opérations particulières
- Division entière : 5 / 2 = 2 , 10 / 3 = 3 , 18 / 5 = 3
- Reste de la division entière (modulo) : 5 % 2 = 1 , 10 % 3 = 1 , 18 % 5 = 3
- Constantes de la librairie `<limits.h>`: `INT_MAX, INT_MIN`
## Les types de base : les réels (`float, double`)
- `Float`: écriture, opérations, exemples complets d'exponentiation
`pow(A,B)``A, B` sont des `double` =\> le résultat est un `double` !
**Attention !** Le calcul effectué par *pow* utilise un logarithmes et une exponentielle.
> Sur 32 bits : 1 bit de signe, 8 bits pour l'exposant et 23 bits pour la mantisse.
- Exemple : coder 19,625 en binaire
> > 19 : 10011 = 2<sup>4</sup> + 2<sup>1</sup> + 2<sup>0</sup>;
0,625 : 0,101 = 2<sup>-1</sup> + 2<sup>-3</sup>
> > 19,625 : 10011,101 = 0,10011101 \* 2<sup>5</sup>
> > Le signe du nombre est stocké sur dans le 1<sup>er</sup> bit (0 positif / 1 négatif).
> > L'exposant est stocké sur 8 positions =\> 256 valeurs =\> -128..127.
> > Donc 5 = 00000101
> > La mantisse de 23 bits stockée est 00111010000000000000000
(le 1<sup>er</sup> 1 est omis car obligatoire)
> > 19,625 stocké en binaire : 0 00000101 00111010000000000000000
- Questions : quelles sont les valeurs les plus petite, grande, petite positive (\>0)?
## Les booléens `bool`
- Librairie: `<stdbool.h>`
Valeurs possibles: `true, false`
Conversion possible en entier
> Exemples:
```C
bool x = true; // booléen vrai
bool x = false; // booléen faux
bool x = 17; // 17 converti en booléen vrai
bool x = -5; // -5 converti en booléen vrai
bool x = 0; // 0 converti en booléen faux
int y = false; // booléen faux converti en 0
int y = true; // booléen vrai converti en 1
```
- Vérification =\> table de vérité
- not (A and B) = (not A) or (not B) : `!(A && B) == (!A)|| (!B)`
- not (A or B) = (not A) and (not B) : `! --|| B) == (!A) && (!B)`
- Opérateurs logiques : `*==, !=, &&, ||, !, <, >, <=, >=`
- Comparaisons bit à bit : `&` (et), `|` (ou), `^` (xor), `!` (not)
- Comparaisons bit à bit avec assignation : `&=, |=, ^=`
## Structures de boucle
- Syntaxe
```C
for (initialisation;condition;increment) {
instructions;
}
while (condition) {
instructions;
}
do {
instructions;
} while (condition);
```
- Instructions : `break, continue`
## Les caractères (type prédéfini) `char`
- On considère les caractères sont des valeurs encodées sur 1 octet (code ASCII étendu).
Il y a donc 256 valeurs possibles. La conversion entre entier et caractère est effective.
Par exemple, le caractère *'A'* correspond à 65 et *'a'* à 96.
```C
char ch = 'a'; // Caractère 'a'
printf("La variable ch est %c\n",ch); // affiche 'a'
char x = 96;
printf("La variable x est %c\n",x); // affiche aussi 'a'
int v = 'a';
printf("La variable v est %d\n",v); // affiche 96
```
## Structures de test
- Syntaxe
```C
if (condition) {
instructions;
} else if (condition) {
instructions;
} else {
instructions;
}
```
## Exemple de boucles (`for, while, do ... while`)
- La factorielle
# Algorithmes et structures de données 2020-21
Contenu du cours 2 du du 23.09.2020
*****
## Plus petit commun multiple (PPCM) de deux nombres
- Algorithme de PPCM: exemple avec 12 et 15
| Tester si| `>, <` ou `=`| |
|-----------|:------------:|:---------|
| | `12 < 15` | |
| | `24 > 15` | |
| | `24 < 30` | |
| | `36 > 30` | |
| | `36 < 45` | |
| | `48 > 45` | |
| | `48 < 60` | |
| | `60 = 60` | **Fin !**|
## Plus grand diviseur commun (PGCD) de deux nombres
- Algorithme naïf du PGCD
- Pseudo-code du calcul du `PGCD` de `N` et `M`
```
si M rem N = 0 alors
PGCD := N
sinon
pour I de sqrt(N) à 1 faire
si N rem I = 0 et M rem I = 0 alors
PGCD := I
exit
fin si
fin pour
fin si
```
- Algorithme d'Euclide : exemple avec N = 35 et M = 60
| Dividende | = | Diviseur \* Quotient | + | Reste |
|:----------:|:----:|:---------------------:|:---:|:-------:|
| 35 | = | 60 \* 0 | + | 35 |
| 60 | = | 35 \* 1 | + | 25 |
| 35 | = | 25 \* 1 | + | 10 |
| 25 | = | 10 \* 2 | + | 5 |
| 10 | = | 5 \* 2 | + | 0 |
> > => PGCD = 5
## Exercice : Montrer que `PGCD(M,N)*PPCM(M,N) = M*N`
- Utiliser la décomposition en facteurs 1<sup>er<sup/>
## Type composé : tableaux statiques à une dimension
- Collection ordonnée d'objets de même type dont le nombre est connu à la compilation
- La taille d'un tableau statique ne peut pas changer en cours d'exécution
- Allocation contiguë en mémoire et sur la pile
```C
int entiers[] = {1,2,3,4,5};
int tab[3];
```
- Accès aux éléments d’un tableau via l’opérateur `[index]``index` est l’indice de l’élément à accéder, `index` va de 0 à la taille du tableau moins un
```C
int premier = entiers[0];
int dernier = entiers[4];
```
> **Attention!** L'accès à un indice hors de l'intervalle zéro à la taille du tableau moins un ne produit pas d'erreur à la compilation, mais possible à l'exécution.
- Tableau de nombres flottants
```C
const int SIZE = 13;
float tab[SIZE];
```
- Initialisation d'un tableau de floats avec `i*i`, puis avec des nombres aléatoires
```C
for (int i=0;i<SIZE;i++) {
tab[i] = (float)rand()/(float)(RAND_MAX) ;
}
```
- Recherche d'un indice de la valeur minimale d'un tableau de floats et permutation avec l'élément en 1<sup>ère</sup> position
- Répétition de l'opération précédente sur des tranches du tableau
- Tri par sélection avec illustration sur un exemple
- Algorithme de vérification que deux mots sont des anagrammes en utilisant un tri
# Algorithmes et structures de données 2020-21
Contenu du cours 3 du 30.09.2020
*****
## Tableaux à deux dimensions
- Image noir et blanc avec des booléens : initialisation
```C
int n = 8, m = 8;
bool image_nb[n][m];
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
image_nb[i][j] = true;
}
}
```
- Image en niveaux de gris : initialisation
```C
int n = 8, m = 8;
int image_gris[n][m];
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
image_gris[i][j] = rand()%256;
}
}
```
>
* Négatif d'une image à 256 niveaux de gris
- Appliquer à chaque pixel l'opération `pixel = 255 - pixel`
```C
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
image_gris[i][j] = 255 - ­image_gris[i][j];
}
}
```
## Type énuméré
- On définit un type énuméré `semaine, coin, mois, couleur, direction` en énumérant toutes ses valeurs possibles.
Explicitement
```C
enum semaine {lu,ma,me,je,ve,sa,di};
enum coin {cinq_cts=5,dix_cts=10,vingt_cts=20,euro=100};
enum mois {
jan=1,feb,mar,apr,mai,jun,jul,aug,sep,oct,nov,dec
};
enum couleur {RED,GREEN,BLUE};
enum direction {EST=2,OUEST=3,NORD=0,SUD=1};
```
> Les valeurs d’un type énuméré peuvent être considérées comme des entiers.
Sans précision particulière, le premier élément correspond à 0 et les suivants à 1, 2, etc.
Sinon on peut explicitement spécifier des valeurs.
Rien n’empêche d'attribuer plusieurs fois le même nombre.
## Opérateur de contrôle `switch`
- Comparaison entre une valeur et un ensemble de choix pour sélectionner une action à effectuer. Toutes les possibilités doivent être prises en compte.
```C
void main() {
type data = id1;
int val;
switch(data) {
case ID1: val = data+1; break;
case ID2: val = data*2; break;
case ID3: val = data/3.0; break;
};
println!(\"val =%d\\n\",val);
}
```
## Exemple de la « couverture de la reine »
```C
enum piece {SAFE,VULN,QUEEN};
int size = 8;
piece board[size][size];
// initialisation de l'échiquier
for (int i=0;i<size;i++) {
for (int j=0;j<size;j++) {
board[i][j] = SAFE;
}
}
int pos_reine[] = {3,4};
// couverture sans les diagonales !!!
for (int k=0;k<size;k++) {
board[k][pos_reine[1]] = VULN;
board[pos_reine[0]][k] = VULN;
}
board[pos_reine[0]][pos_reine[1]] = QUEEN;
```
## Matrices
1. Tableau 2D de nombres
2. Opérations arithmétiques
1. Addition : `C = A+B`
2. Soustraction : `C = A-B`
3. Multiplication : `C = A*B` (produit lignes/colonnes)
4. Puissance entière : `C = A`<sup>n</sup>
# Algorithmes et structures de données 2020-21
Contenu du cours 4 du 7.10.2020
*****
## Crible d’Eratosthène
- Retour sur les tableaux à 1 dimension
## Type article (enregistrement, record) : `struct`
- Un article permet de regrouper des types de nature différente (appelés champs) comme composant d'un type composé.
- Exemples de `struct`:
```C
struct fraction {
int num;
int den;
};
enum mois {
jan=1,feb,mar,apr,mai,jun,jul,aug,sep,oct,nov,dec
};
struct date {
int day;
mois month;
int year;
}
enum sexe {FEM, MASC, AUTRE};
struct employe {
char nom[80];
sexe genre;
int age;
float salaire;
}
```
## Fonction cube d'un nombre
```C
int cube(int x) {
return x*x*x;
}
```
## Fonction de parité
```C
bool est_pair(int n) {
return n%2 == 0;
}
```
## Plus Petit Commun Multiple (PPCM)
- Fonction PPCM: `int ppcm(int n,int m);`
## Plus Grand Commun Diviseur (PGCD)
- Fonction PGCD: `nt pgcd(int n,int m);`
## Paramètres de fonction
- Dans le langage C, les paramètres des fonctions sont toujours passés par copie.
Ainsi, la valeur d'une variable passée en paramètre à une fonction n'est pas modifiée,
puisque c'est une copie de cette variable qui est passée effectivement à la fonction.
Toutes les manipulations effectuées par la fonction le sont donc sur cette copie.
Celle-ci est détruite à la fin de l'exécution de la fonction, laissant la variable originelle inchangée.
- Pour que des modifications puissent subsister après l'exécution, on peut procéder de deux manières :
1. en retournant une valeur par la fonction ;
2. en passant en paramètre un pointeur : celui-ci donne accès à une
zone mémoire hors de la portée (scope) de la fonction, zone qui
peut donc être modifiée durablement.
- Fonction d'incrément
```C
void sans_effet(int x) {
x++;
}
void increment(int* x) {
(*x)++;
}
void main() {
int a = 2;
sans_effet(a);
printf("a=%d",a); // imprime 2, valeur de a inchangée
increment(&a);
printf(\"a=%d\",a); // imprime 3
}
```
## Zones d'allocation mémoire
- Un programme utilise deux types de zone mémoire lors de son exécution pour stocker les variables : la pile et le tas.
- A l'exécution d'un programme, les allocations de variables :
1. sur la pile, sont faites par le système d'exploitation
- dans ce cas, on parle de variables statiques
2. sur le tas, sont de la responsabilité de la programmeuse via un appel à la fonction `malloc()`
- dans ce cas, on parle de variables dynamiques
- La désallocation d'une variable statique survient lors de la sortie de sa portée (scope) et est donc automatique.
- Une variable dynamique doit être explicitement désallouée par la programmeuse avec un appel à la fonction `free()`.
- Il y a parfois une petite confusion entre la zone mémoire où réside un pointeur et celle où se situe l'espace pointé par le pointeur.
- Par exemple, l’instruction
`char* ptr_ch = malloc(3*sizeof(char));`
alloue un espace sur le tas pour 3 caractères, alors que la variable `ptr_ch` est allouée sur la pile.
## Pseudo-code du tri par sélection
```
procedure tri_selection(tableau t[0..n­-1])
begin
for i = 0 to n-­2 do
ind_min := index_min(t[i..n-­1])
if t[ind_min] ≠ t[i] then
echanger(t[i],t[ind_min])
end if
end for
end tri_selection
```