Corrigé Bac
Sujet 2023 - Jour 2 (21/03/2023) - Spécialité NSI - Corrigé

Sujet bac : annale 21 mars 2023

EXERCICE 1 (3 points)

$\bold{1.}$ Table des coûts du nœud $\text{B}$ :

Nœud $\text{B}$
Destination Coût
$\text{A}$ $1$
$\text{C}$ $3$
$\text{D}$ $2$
$\text{E}$ $2$
$\text{F}$ $2$
$\text{G}$ $1$
$\text{H}$ $2$

Table des coûts du nœud $\text{F}$ :

Nœud $\text{F}$
Destination Coût
$\text{A}$ $1$
$\text{B}$ $2$
$\text{C}$ $3$
$\text{D}$ $2$
$\text{E}$ $1$
$\text{G}$ $2$
$\text{H}$ $3$

$\bold{2.}$ Les chemins recherchés sont les chemins reliant $\text{F}$ à $\text{H}$, de coût $3$, à savoir :

  • $\text{F} \to \text{E} \to \text{G} \to \text{H}$
  • $\text{F} \to \text{A} \to \text{G} \to \text{H}$
bannière astuce

Astuce

Le protocole RIP ne choisit que les chemins de coût le moins élevé. Ce coût étant de $3$, seuls les chemins présentant ce coût doivent être recherchés. $\text{F}\to \text{A} \to \text{D}\to \text{C}\to \text{H}$ est un chemin reliant $\text{F}$ à $\text{H}$ de coût $4$, on l’ignore donc.

$\bold{3.}$ On repère les nœuds qui sont à une distance de $1$ du nœud $\text{Z}$, car cela veut dire qu’ils sont voisins de $\text{Z}$.

Schéma du réseau Schéma du réseau avec le nœud Z

bannière astuce

Astuce

Notons que si la consigne imposait que les tables de coûts précédentes demeurent inchangées, alors il aurait fallu procéder comme suit pour ajouter le nœud $\text{Z}$ :

Schéma du réseau Schéma du réseau avec le nœud Z - autre solution

$\bold{4.}$ On identifie tous les chemins menant de $\text{B}$ à $\text{H}$ qui n’empruntent les nœuds qu’une seule fois, et on calcule leur coût associé :

Chemin Coût
$\text{B} \to \text{G}\to \text{H}$ $1+100=101$
$\text{B} \to \text{G}\to \text{A} \to \text{D}\to \text{C} \to \text{H}$ $1+10+10+10+10=41$
$\text{B} \to \text{G}\to \text{E} \to \text{F}\to \text{A} \to \text{D}\to \text{C}\to \text{H}$ $1+1+1+1+10+10+10=34$
$\text{B} \to \text{A} \to \text{D}\to \text{C} \to \text{H}$ $10+10+10+10=40$
$\text{B} \to \text{A} \to \text{G} \to \text{H}$ $10+10+100=120$
$\text{B} \to \text{A}\to \text{F} \to \text{E}\to \text{G} \to \text{H}$ $10+1+1+1+100=113$

Le chemin présentant le coût le moins élevé est donc $\text{B} \to \text{G}\to \text{E} \to \text{F}\to \text{A} \to \text{D}\to \text{C}\to \text{H}$ dont le coût est de $34$. On remarque qu’avec le protocole RIP, ce chemin aurait été écarté d’office car il présente le nombre de sauts le plus grand.

bannière astuce

Astuce

On peut avoir l’intuition d’éviter les chemins passant par $\text{G}-\text{H}$ car le coût est très élevé, mais lister tous les chemins permet d’en être sûr par une démarche rigoureuse.

EXERCICE 2 (3 points)

$\bold{1.a.}$ Une clé primaire est un attribut ou un ensemble d’attributs qui permet d’identifier de manière unique chaque enregistrement dans une table.

$\bold{1.b.}$ Cette requête SQL a pour but d’ajouter un nouvel enregistrement à la table $\text{Astronaute}$ dont la valeur de l’attribut $\text{id\textunderscore astronaute}$ est $3$. Or l’attribut $\text{id\textunderscore astronaute}$ est une clé primaire. Il ne peut donc contenir que des valeurs uniques.
Dans la table $\text{Astronaute}$, il se trouve déjà un enregistrement dont la valeur de l’attribut $\text{id\textunderscore astronaute}$ est $3$. La requête SQL provoque donc une erreur puisqu’elle ne peut être exécutée.

bannière astuce

Astuce

Pour rappel, les valeurs d’attributs renseignées dans la requête SQL sont données dans l’ordre des attributs utilisés dans la définition de la table, donnée dans l’énoncé ($\text{id\textunderscore astronaute}$, $\text{nom}$, $\text{prenom}$, $\text{nationalite}$, $\text{nb\textunderscore vols}$).

$\bold{1.c.}$
$\text{Fusee}$ ($\underline{\text{id\textunderscore fusee}}$ : $\text{INT, modele}$ : $\text{TEXT, constructeur}$ : $\text{TEXT, nb \textunderscore places}$ : $\text{INT}$)

bannière attention

Attention

Penser à souligner l’attribut correspondant à la clé primaire.

$\bold{2.a.}$ Cette requête renvoie le nombre $2$. Il s’agit du nombre d’enregistrements dans la table $\text{Fusee}$ dont l’attribut $\text{Constructeur}$ a pour valeur $\text{SpaceX}$.

bannière astuce

Astuce

C’est la clause $\text{COUNT(*)}$ dans la requête SQL qui permet d’effectuer le compte.

$\bold{2.b.}$
$$\begin{aligned}&\text{SELECT modele, constructeur} \\ &\text{FROM Fusee}\\ &\text{WHERE nb\textunderscore places} >=4\text{;}\end{aligned}$$

Sachant que $\text{nb\textunderscore places}$ est un entier, il est également possible d’écrire la clause $\text{WHERE}$ comme suit :
$$\text{WHERE nb\textunderscore places}>3$$

$\bold{2.c.}$
$$\begin{aligned}&\text{SELECT nom, prenom} \\ &\text{FROM Astronaute}\\ &\text{ORDER BY nom ASC;}\end{aligned}$$

bannière astuce

Astuce

Sans clause supplémentaire à la clause $\text{ORDER BY}$, l’ordre pris par défaut est ascendant. La clause $\text{ASC}$ est donc ici facultative.

$\bold{3.a.}$
$$\begin{aligned} &\text{/* Ajout de l’enregistrement concernant le vol /}\\ &\text{ INSERT INTO Vol VALUES(5, 3, ‘12/04/2023’) ;}\\ &\text{/ Ajout de l’enregistrement concernant le premier astronaute de l’équipage /}\\ &\text{ INSERT INTO Equipe VALUES(5, 1);}\\ &\text{/ Ajout de l’enregistrement concernant le second astronaute de l’équipage */}\\ &\text{ INSERT INTO Equipe VALUES(5, 4) ;} \end{aligned}$$

bannière attention

Attention

On peut noter une erreur dans l’énoncé concernant la table $\text{Equipe}$.
L’attribut $\text{id\textunderscore vol}$ est une clé étrangère, au même titre que l’attribut $\text{id\textunderscore astronaute}$, il doit donc être précédé d’un « # ». Et la clé primaire de cette table est constituée des deux clés étrangères $\text{id\textunderscore vol}$ et $\text{id\textunderscore astronaute}$, et non uniquement de $\text{id\textunderscore vol}$.

$\bold{3.b.}$
$$\begin{aligned} &\text{SELECT nom, prenom}\\ &\text{FROM Astronaute }\\ &\text{JOIN Equipe ON Astronaute.id\textunderscore astronaute = Equipe.id\textunderscore astronaute }\\ &\text{JOIN Vol ON Equipe.id\textunderscore vol = Vol.id\textunderscore vol }\\ &\text{WHERE vol.Date = ‘25/10/2022’ ;} \end{aligned}$$

Une syntaxe alternative à celle de la requête précédente est la suivante :

$$\begin{aligned} &\text{SELECT nom, prenom}\\ &\text{FROM Astronaute }\\ &\text{WHERE Astronaute.id\textunderscore astronaute = Equipe.id\textunderscore astronaute }\\ &\text{AND Equipe.id\textunderscore vol = Vol.id\textunderscore vol }\\ &\text{AND vol.Date = ‘25/10/2022’ ;} \end{aligned}$$

EXERCICE 3 (6 points)

Partie 1

$\bold{1.}$ La taille de l’arbre binaire en figure 1 est de $5$. La hauteur de cet arbre binaire est de $3$.

$\bold{2.}$ On utilise le principe suivant : si l’étiquette est avant celle de la racine de l’arbre courant, alors on se place sur le sous-arbre à sa gauche. Sinon, on se place sur le sous-arbre à sa droite. On réitère l’opération jusqu’à tomber sur une place vacante.

Arbre binaire de recherche complété Arbre binaire de recherche complété

$\bold{3.}$ $\bold{C}$ - parcours en profondeur dans l’ordre infixe.

bannière astuce

Astuce

Pour rappel, l’ordre infixe consiste à parcourir le sous-arbre de gauche, puis le nœud, puis le sous-arbre de droite.

$\bold{4.}$
$$\begin{aligned} &\text{def present(self, identifiant):} \\ &\qquad\text{if self.est\textunderscore vide():}\\ &\qquad\qquad\text{return False}\\ &\qquad\text{elif self.racine() == identifiant:} \\ &\qquad\qquad\text{return True}\\ &\qquad\text{elif self.racine() < identifiant:} \\ &\qquad\qquad\text{return self.sd().present(identifiant)} \\ &\qquad\text{else:} \\ &\qquad\qquad\text{return self.sg().present(identifiant)} \end{aligned}$$

bannière astuce

Astuce

La méthode est récursive car sa définition fait appel à elle-même dans les appels $\text{self.sd().present(identifiant)}$ et $\text{self.sg().present(identifiant)}$.

Partie 2

$\bold{5.a.}$ La file f1 donnée dans l’énoncé est constituée de 4 éléments, donc n’est pas vide.
L’appel de la fonction $\text{est\textunderscore vide(f1)}$ renvoie donc $\text{False}$.

$\bold{5.b.}$ Comme indiqué dans l’énoncé, la fonction $\text{defiler(f)}$ retire l’élément situé à la tête de la file $\text{f}$, c’est-à-dire tout à droite dans son illustration et retourne la valeur de cet élément.
L’appel de la fonction $\text{defiler(f1)}$ renvoie donc $\text{file}$ et modifie la file $\text{f1}$ comme suit :

$\text{‘bac’}$ $\text{‘nsi’}$ $\text{‘2023’}$

$\bold{5.c.}$ Comme indiqué dans l’énoncé, la fonction $\text{enfiler(f, e)}$ ajoute l’élément $\text{e}$ à la queue de la file $\text{f}$, c’est-à-dire tout à gauche dans son illustration.
Le code crée la file $\text{f2}$ suivante :

$\text{‘poule’}$ $\text{‘python’}$ $\text{‘castor’}$

$\bold{6.}$ Pour compter, cette fonction fait défiler la file $\text{f}$ jusqu’à ce que celle-ci soit vide. Dans le même temps, à chaque appel de la fonction $\text{defiler(f)}$, elle incrémente son compteur et sauvegarde dans la file $\text{g}$ l’élément supprimé de la file $\text{f}$. Une fois la file $\text{f}$ vide, la fonction restaure le contenu de la file $\text{f}$ en défilant la file $\text{g}$ dans la file $\text{f}$.

$$\begin{aligned} &\text{def longueur(f):} \\ &\qquad\text{resultat = 0}\\ &\qquad\text{g = creer\textunderscore file()}\\ &\qquad\text{while \textcolor{violet}{not(est\textunderscore vide(f))}:}\\ &\qquad\qquad\text{elt = defiler(f)}\\ &\qquad\qquad\text{resultat = \textcolor{violet}{resultat + 1}}\\ &\qquad\qquad\text{enfiler(\textcolor{violet}{g}, \textcolor{violet}{elt})}\\ &\qquad\text{while not(est\textunderscore vide(g)):}\\ &\qquad\qquad\text{enfiler(f, defiler(g))}\\ &\qquad\text{return resultat} \end{aligned}$$

$\bold{7.}$ La fonction vérifie que le mot de passe :

  • contient au moins 8 caractères
  • contient au moins l’un des caractères suivants : ‘!’, ‘#’, ‘@’, ‘;’, ‘:’

$\bold{A}$ - $\text{‘best@’}$ ne convient pas car ne remplit pas la première condition.
$\bold{B}$ - $\text{‘paptap23’}$ ne convient pas car ne remplit pas la seconde condition.
Le mot de passe qui sera validé par la fonction est : $\bold{C}$ - $\text{‘2!@59fgds’}$.

$\bold{8.}$ Il est nécessaire de défiler la file $\text{f}$ passée en paramètres si elle fait une longueur de $3$ car le fait d’enfiler ensuite la chaîne de caractères $\text{mdp}$ ajoute un élément à $\text{f}$. Or la consigne est que $\text{f}$ n’ait pas plus de $3$ éléments.

$$\begin{aligned} &\text{ def ajouter\textunderscore mot(f, mdp):} \\ &\qquad\text{if longueur(f) > 3 :}\\ &\qquad\qquad\text{defiler(f)}\\ &\qquad\text{enfiler(f, mdp)} \end{aligned}$$

$\bold{9.}$ La fonction $\text{mot\textunderscore file}$ fait défiler un à un tous les éléments de la liste $\text{f}$ passée en paramètre, et les compare avec la chaîne de caractères $\text{mdp}$ passée également en paramètre. Si elle détecte une égalité, elle positionne la variable booléenne $\text{present}$ à $\text{True}$, variable initialisée à $\text{False}$.
Une fois la file $\text{f}$ épuisée, la fonction la restaure en y enfilant les éléments qu’elle a sauvegardé dans la file $\text{g}$ créée à cet effet.

$$\begin{aligned} &\text{ def mot\textunderscore file(f, mdp):}\\ &\qquad\text{g = creer\textunderscore file()}\\ &\qquad\text{present = False}\\ &\qquad\text{while not(est\textunderscore vide(f)):}\\ &\qquad\qquad\text{elt = defiler(f)}\\ &\qquad\qquad\text{enfiler(g, elt)}\\ &\qquad\qquad\text{if \textcolor{violet}{elt == mdp}:}\\ &\qquad\qquad\qquad\text{present = \textcolor{violet}{True}}\\ &\qquad\text{while not(est\textunderscore vide(g)):}\\ &\qquad\qquad\text{enfiler(f, defiler(g))}\\ &\qquad\text{return present} \end{aligned}$$

$\bold{10.}$
$$\begin{aligned} &\text{def modification(f, nv\textunderscore mdp):} \\ &\qquad\text{if est\textunderscore valide(nv\textunderscore mdp):}\\ &\qquad\qquad\text{if mot\textunderscore file(f, nv\textunderscore mdp):}\\ &\qquad\qquad\qquad\text{return False}\\ &\qquad\qquad\text{else}\\ &\qquad\qquad\qquad\text{ajouter\textunderscore mot(f, nv\textunderscore mdp)}\\ &\qquad\qquad\qquad\text{return True}\\ &\qquad\text{else}\\ &\qquad\qquad\text{return False} \end{aligned}$$

Une autre rédaction plus compacte pour le code de cette fonction est la suivante :

$$\begin{aligned} &\text{def modification(f, nv\textunderscore mdp):} \\ &\qquad\text{if est\textunderscore valide(nv\textunderscore mdp) and mot\textunderscore file(f, nv\textunderscore mdp):}\\ &\qquad\qquad\text{ajouter\textunderscore mot(f, nv\textunderscore mdp)}\\ &\qquad\qquad\text{return True}\\ &\qquad \text{return False} \end{aligned}$$

Son avantage est que le nombre d’instructions y est réduit, mais sa lisibilité en est un peu altérée.