diff --git a/slides/cours_10.md b/slides/cours_10.md new file mode 100644 index 0000000000000000000000000000000000000000..ca2cdc1b99fb910ee0e419a5f0b1465ec2d9722c --- /dev/null +++ b/slides/cours_10.md @@ -0,0 +1,452 @@ +--- +title: "Piles et files d'attente" +date: "2021-12-08" +patat: + eval: + tai: + command: fish + fragment: false + replace: true + ccc: + command: fish + fragment: false + replace: true + images: + backend: auto +... + +# La liste chaînée et pile (1/N) + +## Structure de données + +* Chaque élément de la liste contient: + 1. une valeur, + 2. un pointeur vers le prochain élément. +* La pile est un pointeur vers le premier élément. + +{width=80%} + +# La liste chaînée et pile (2/N) + +## Une pile-liste-chaînée + +```C +typedef struct _element { + int data; + struct _element *next; +} element; +typedef element* stack; +``` + +## Fonctionnalités? + +. . . + +```C +void stack_create(stack *s); // *s = NULL; +void stack_destroy(stack *s); +void stack_push(stack *s, int val); +void stack_pop(stack *s, int *val); +void stack_peek(stack s, int *val); +bool stack_is_empty(stack s); // reutrn NULL == stack; +``` + +# La liste chaînée et pile (3/N) + +## Empiler? (faire un dessin) + +. . . + +```C + + + + + + + +``` + +## Empiler? (le code ensemble) + +. . . + +```C +void stack_push(stack *s, int val) { + element *elem = malloc(sizeof(*elem)); + elem->data = val; + elem->next = *stack; + stack = elem; +} +``` + +# La liste chaînée et pile (4/N) + +## Jeter un oeil? (faire un dessin) + +. . . + +```C + + + + + + + +``` + +## Jeter un oeil? (le code ensemble) + +. . . + +```C +void stack_peek(stack s, int *val) { + *val = s->data; +} +``` + +# La liste chaînée et pile (5/N) + +## Dépiler? (faire un dessin) + +. . . + +```C + + + + + + + +``` + +## Dépiler? (le code ensemble) + +. . . + +```C +void stack_pop(stack *s, int *val) { + stack_peek(*s, val); + element *tmp = *s; + *s = (*s)->next; + free(tmp); + return val; +} +``` + +# La liste chaînée et pile (6/N) + +## Détruire? (faire un dessin) + +. . . + +```C + + + + + + + +``` + +## Détruire? (le code ensemble) + +. . . + +```C +void stack_destroy(stack *s) { + while (!stack_is_empty(*s)) { + int val = stack_pop(s); + } +} +``` + +# La file d'attente (1/N) + +* Structure de données abstraite permettant le stockage d'éléments. +* *FIFO*: First In First Out, ou première entrée première sortie. +* Analogue de la vie "réelle"": + * File à un guichet, + * Serveur d'impressions, + * Mémoire tampon, ... + +## Fonctionnalités + + . . . + +* Enfiler, ajouter un élément à la fin de la file. +* Défiler, extraire un élément au devant de la file. +* Tester si la file est vide. + +. . . + +* Lire l'élément de la fin de la file. +* Lire l'élément du devant de la file. +* Créer une liste vide. +* Détruire une liste vide. + +# La file d'attente (2/N) + +## Implémentation possible + +* La structure file, contient un pointeur vers la tête et un vers la queue. +* Entre les deux, les éléments sont stockés dans une liste chaînée (comme une + pile). + + + +## Structure de données en C? + +. . . + +```C +txpedef struct _element { // Elément de liste + int data; + struct _element* next; +} element; + +typedef struct _queue { // File d'attente: + element* head; // tête de file d'attente + element* tail; // queue de file d'attente +} queue; +``` + +# Fonctionnalités d'une file d'attente (gitlab) + +## Creation et consultations + +. . . + +```C +void queue_init(queue *fa); // head = tail = NULL +bool queue_is_empty(queue fa); // fa.head == fa.tail == NULL +int queue_tail(queue fa); // return fa.head->data +int queue_head(queue fa); // return fa.tail->data +``` + +## Manipulations et destruction + +. . . + +```C +void queue_enqueue(queue *fa, int val); // adds an element before the tail +int queue_dequeue(queue *fa); // removes the head and returns stored value +void queue_destroy(queue *fa); // dequeues everything into oblivion +``` + +# Enfilage + +## Deux cas différents: + +1. La file est vide (faire un dessin): + +. . . + +{width=40%} + +2. La file n'est pas vide (faire un dessin): + +. . . + +{width=70%} + +# Enfilage + +## Live (implémentation) + +. . . + +```C + +``` + + + + +# Défilage + +## Trois cas différents + +1. La file a plus d'un élément (faire un dessin): + +. . . + +{width=80%} + +2. La file un seul élément (faire un dessin): + +. . . + +{width=25%} + + +3. La file est vide (problème) + +# Défilage + +## Live (implémentation) + +. . . + +```C + +``` + +# Destruction + +## Comment on faire la désallocation? + +. . . + +On défile jusqu'à ce que la file soit vide! + +# Complexité + +## Quelle sont les complexité de: + +* Enfiler? + +. . . + +* Dépiler? + +. . . + +* Détruire? + +. . . + +* Est vide? + + +# Implémentation alternative + +## Comment implémenter la file auterment? + +. . . + +* Données stockées dans un tableau; +* Tableau de taille connue à la compilation ou pas (reallouable); +* `head` et `tail` seraient les indices du tableau; +* `capacity` seraient la capacité maximale; + +. . . + +## Structure de données + +```C +typedef struct _queue { + int *data; + int head, tail, capacity; +} queue; +``` + +# File basée sur un tableau + +* Initialisation? + +. . . + +```C + + + + +``` + +* Est vide? + +. . . + +```C + + + + +``` + + +* Empiler? + +. . . + +```C + + + + +``` + +* Dépiler? + +. . . + +```C + + + + +``` + +# Complexité + +## Quelle sont les complexité de: + +* Initialisation? + +. . . + +```C + + + + +``` + +* Est vide? + +. . . + +```C + +``` + + +* Empiler? + +. . . + +```C + + + + +``` + +* Dépiler? + +. . . + +```C + + + + +``` + + +# File basée sur un tableau (git) + +* Créons le squelette et `Makefile` ensemble. + +. . . + +* Créons quelques issues et assignons les! + + diff --git a/slides/cours_9.md b/slides/cours_9.md index 30610c51777efb2766856658473a67deb332a3a7..9a03c1703ebdacf724edc12d51c1e53cfba3494c 100644 --- a/slides/cours_9.md +++ b/slides/cours_9.md @@ -507,267 +507,3 @@ bool evaluate(char *postfix, double *val) { // init stack } ``` -# La liste chaînée et pile (1/N) - -## Structure de données - -* Chaque élément de la liste contient: - 1. une valeur, - 2. un pointeur vers le prochain élément. -* La pile est un pointeur vers le premier élément. - -{width=80%} - -# La liste chaînée et pile (2/N) - -## Une pile-liste-chaînée - -```C -typedef struct _element { - int data; - struct _element *next; -} element; -typedef element* stack; -``` - -## Fonctionnalités? - -. . . - -```C -void stack_create(stack *s); // *s = NULL; -void stack_destroy(stack *s); -void stack_push(stack *s, int val); -void stack_pop(stack *s, int *val); -void stack_peek(stack s, int *val); -bool stack_is_empty(stack s); // reutrn NULL == stack; -``` - -# La liste chaînée et pile (3/N) - -## Empiler? (faire un dessin) - -. . . - -```C - - - - - - - -``` - -## Empiler? (le code ensemble) - -. . . - -```C -void stack_push(stack *s, int val) { - element *elem = malloc(sizeof(*elem)); - elem->data = val; - elem->next = *stack; - stack = elem; -} -``` - -# La liste chaînée et pile (4/N) - -## Jeter un oeil? (faire un dessin) - -. . . - -```C - - - - - - - -``` - -## Jeter un oeil? (le code ensemble) - -. . . - -```C -void stack_peek(stack s, int *val) { - *val = s->data; -} -``` - -# La liste chaînée et pile (5/N) - -## Dépiler? (faire un dessin) - -. . . - -```C - - - - - - - -``` - -## Dépiler? (le code ensemble) - -. . . - -```C -void stack_pop(stack *s, int *val) { - stack_peek(*s, val); - element *tmp = *s; - *s = (*s)->next; - free(tmp); - return val; -} -``` - -# La liste chaînée et pile (6/N) - -## Détruire? (faire un dessin) - -. . . - -```C - - - - - - - -``` - -## Détruire? (le code ensemble) - -. . . - -```C -void stack_destroy(stack *s) { - while (!stack_is_empty(*s)) { - int val = stack_pop(s); - } -} -``` - -# La file d'attente (1/N) - -* Structure de données abstraite permettant le stockage d'éléments. -* *FIFO*: First In First Out, ou première entrée première sortie. -* Analogue de la vie "réelle"": - * File à un guichet, - * Serveur d'impressions, - * Mémoire tampon, ... - -## Fonctionnalités - - . . . - -* Enfiler, ajouter un élément à la fin de la file. -* Défiler, extraire un élément au devant de la file. -* Tester si la file est vide. - -. . . - -* Lire l'élément de la fin de la file. -* Lire l'élément du devant de la file. -* Créer une liste vide. -* Détruire une liste vide. - -# La file d'attente (2/N) - -## Implémentation possible - -* La structure file, contient un pointeur vers la tête et un vers la queue. -* Entre les deux, les éléments sont stockés dans une liste chaînée (comme une - pile). - - - -## Structure de données en C? - -. . . - -```C -txpedef struct _element { // Elément de liste - int data; - struct _element* next; -} element; - -typedef struct _queue { // File d'attente: - element* head; // tête de file d'attente - element* tail; // queue de file d'attente -} queue; -``` - -# Fonctionnalités d'une file d'attente (gitlab) - -## Creation et consultations - -. . . - -```C -void queue_init(queue *fa); // head = tail = NULL -bool queue_is_empty(queue fa); // checks if queue is empty -int queue_tail(queue fa); // returns the value of the tail -int queue_head(queue fa); // returns the value of the head -``` - -## Manipulations et destruction - -. . . - -```C -void queue_enqueue(queue *fa, int val); // adds an element before the tail -int queue_dequeue(queue *fa); // removes the head and returns stored value -void queue_destroy(queue *fa); // dequeues everything into oblivion -``` - -# Enfilage - -## Deux cas différents: - -1. La file est vide (faire un dessin): - -. . . - -{width=40%} - -2. La file n'est pas vide (faire un dessin): - -. . . - -{width=70%} - -# Défilage - -## Trois cas différents - -. . . - -1. La file est vide (problème). -2. La file a plus d'un élément (faire un dessin) - -. . . - - - -3. La file a un seul élément (faire un dessin) - -Si la file d'attente n'avait qu'un seul élément, alors il faudrait mettre le pointeur `fa->debut` à `NULL`. -Dans ce cas, à la suite du point (3), le pointeur `fa->tete` se retrouve à `NULL`. On doit donc ajouter l'instruction : - -```C - if (NULL == fa>tete) { - fa>debut = NULL; - } -``` diff --git a/slides/figs/fig_queue_extract.png b/slides/figs/fig_queue_extract.png new file mode 100644 index 0000000000000000000000000000000000000000..a31dfba6e27cc7cfbe046fef3158da529a93f55d Binary files /dev/null and b/slides/figs/fig_queue_extract.png differ diff --git a/slides/figs/fig_queue_extract_one.svg b/slides/figs/fig_queue_extract_one.svg new file mode 100644 index 0000000000000000000000000000000000000000..7778d437df4c3b3967ef2cfb21a9b1430c561b68 --- /dev/null +++ b/slides/figs/fig_queue_extract_one.svg @@ -0,0 +1,298 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="71.796646mm" + height="55.054691mm" + viewBox="0 0 71.796646 55.054692" + version="1.1" + id="svg26163" + inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)" + sodipodi:docname="fig_queue_extract_one.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview26165" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:document-units="mm" + showgrid="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:zoom="1.2953002" + inkscape:cx="183.35518" + inkscape:cy="147.84217" + inkscape:window-width="1920" + inkscape:window-height="1080" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" /> + <defs + id="defs26160"> + <marker + style="overflow:visible" + id="Arrow2Lend" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend" + inkscape:isstock="true"> + <path + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.625;stroke-linejoin:round" + id="path8989" /> + </marker> + <marker + style="overflow:visible" + id="Arrow2Lend-7" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend" + inkscape:isstock="true"> + <path + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.625;stroke-linejoin:round" + id="path8989-5" /> + </marker> + <marker + style="overflow:visible" + id="Arrow2Lend-7-3" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend" + inkscape:isstock="true"> + <path + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.625;stroke-linejoin:round" + id="path8989-5-6" /> + </marker> + <marker + style="overflow:visible" + id="Arrow2Lend-7-2" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend" + inkscape:isstock="true"> + <path + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.625;stroke-linejoin:round" + id="path8989-5-9" /> + </marker> + <marker + style="overflow:visible" + id="Arrow2Lend-7-27" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="Arrow2Lend" + inkscape:isstock="true"> + <path + transform="matrix(-1.1,0,0,-1.1,-1.1,0)" + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z" + style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.625;stroke-linejoin:round" + id="path8989-5-0" /> + </marker> + </defs> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-38.04528,-128.39909)"> + <g + id="g27567"> + <rect + style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-opacity:1" + id="rect849" + width="32.000549" + height="13.894769" + x="61.211033" + y="163.60229" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 77.211308,163.81338 v 13.47261" + id="path986" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:3.52777px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="63.648254" + y="167.44313" + id="text3270"><tspan + sodipodi:role="line" + id="tspan3268" + x="63.648254" + y="167.44313" + style="stroke-width:0.264583">data</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:3.52777px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="80.402161" + y="167.34151" + id="text3270-3"><tspan + sodipodi:role="line" + id="tspan3268-6" + x="80.402161" + y="167.34151" + style="stroke-width:0.264583">next</tspan></text> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)" + d="M 90.506705,170.55434 H 101.39839" + id="path8966" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend-7)" + d="m 57.156648,151.19704 9.957227,11.4829" + id="path8966-3" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend-7-3)" + d="m 57.070207,134.41304 13.529066,8.95621" + id="path8966-3-0" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.529167, 0.264583;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow2Lend-7-2)" + d="m 79.884799,151.13428 -8.461285,11.75329" + id="path8966-3-1" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.529167, 0.264583;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow2Lend-7-27)" + d="m 99.450797,151.13241 -25.53153,11.89643" + id="path8966-3-9" + sodipodi:nodetypes="cc" /> + <g + id="g19539" + transform="matrix(0.26458333,0,0,0.26458333,50.232802,175.83868)"> + <g + id="g14281" + transform="translate(-30.526542,-27.424011)"> + <rect + style="fill:#ffffff;stroke:#000000;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect9442" + width="71.481941" + height="28.485205" + x="-14.786533" + y="-94.194954" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:13.3333px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none" + x="5.6842546" + y="-74.981659" + id="text11594"><tspan + sodipodi:role="line" + id="tspan11592" + x="5.6842546" + y="-74.981659">elmt</tspan></text> + </g> + </g> + <g + id="g19533" + transform="matrix(0.26458333,0,0,0.26458333,50.232802,175.83868)"> + <rect + style="fill:#ffffff;stroke:#000000;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect14815" + width="139.78581" + height="29.670931" + x="76.975639" + y="-122.71912" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:13.3333px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none" + x="90.747475" + y="-103.29707" + id="text16175"><tspan + sodipodi:role="line" + id="tspan16173" + x="90.747475" + y="-103.29707">tete</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:13.3333px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none" + x="167.53326" + y="-102.91296" + id="text16175-5"><tspan + sodipodi:role="line" + id="tspan16173-6" + x="167.53326" + y="-102.91296">debut</tspan></text> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 146.86855,-122.04171 v 28.316121" + id="path17624" /> + </g> + <g + id="g24610" + transform="matrix(0.26458333,0,0,0.26458333,50.232802,175.83868)"> + <rect + style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect20383" + width="33.501225" + height="22.229925" + x="-7.6590633" + y="-178.79926" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:13.3333px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none" + x="3.1117313" + y="-162.71361" + id="text21875"><tspan + sodipodi:role="line" + id="tspan21873" + x="3.1117313" + y="-162.71361">fa</tspan></text> + </g> + <g + id="g25290" + transform="matrix(0.26458333,0,0,0.26458333,50.232802,175.83868)"> + <rect + style="fill:#ffffff;stroke:#000000;stroke-width:3.77953;stroke-opacity:1" + id="rect9338" + width="25.912838" + height="48.277096" + x="197.49173" + y="-44.128456" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 198.44004,-28.851968 13.81444,-13.814444" + id="path25192" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 198.16174,-17.266685 24.00548,-24.005477" + id="path25194" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 198.02184,-6.705438 25.33761,-25.337608" + id="path25198" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 197.49173,4.1486397 223.4456,-21.805234" + id="path25200" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 208.19521,4.2844338 223.75226,-11.272625" + id="path25202" /> + </g> + </g> + <path + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 57.951433,161.18156 40.25922,21.83269" + id="path27602" /> + <path + style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 98.210653,161.18156 -40.25922,21.83269" + id="path27602-6" /> + </g> +</svg>