Corrigé Bac Sujet 2025 - Jour 1 - Asie - Spécialité NSI - Corrigé

Sujet bac : annale 2025 – Asie – Jour 1

EXERCICE 1 (6 points)

$\bold{1}$

Les variables prennent les valeurs successives suivantes :

variable NSI

Après l’exécution du programme, $x = 0$ et $y = 20$.

$\bold{2}$

Un programme Python est écrit et stocké dans un fichier texte. Il peut donc être vu comme une chaîne de caractères.

$\bold{3}$

La variable « programme 3 » termine. En effet, la condition d’arrêt de la boucle est « $x = 0$ » et celle-ci est remplie après que la variable $x$ a pris successivement les valeurs 10, 8, 6, 4, 2 puis 0.

La variable « programme 4 » ne termine pas. En effet, la condition d’arrêt de la boucle est « $x < 0$ » et celle-ci n’est jamais remplie car la variable $x$ prend des valeurs strictement positives et croissantes (10, 12, …).

La variable « programme 5 » termine. En effet, la condition d’arrêt de la boucle est « $x > 0$ » et celle-ci est immédiatement remplie puisque $x$ est initialisée à 10.

La variable « programme 6 » ne termine pas. En effet, la condition d’arrêt de la boucle est « $x = 0$ » et celle-ci n’est jamais remplie car $x$ prend successivement les valeurs décroissantes 10, 6, 2, -2, -6, … sans jamais prendre la valeur 0.

$\bold{4}$

Cette fonction exécute le programme qui lui est passé en paramètre. Si ce programme termine, elle retourne ensuite la valeur True . En revanche, si le programme ne termine pas, la fonction elle-même ne termine pas et ne peut donc pas retourner la valeur $\text{False}$. Cette fonction ne répond donc pas complètement au problème posé.

$\bold{5}$

L’algorithme de Boyer Moore permet d’optimiser la recherche d’une chaîne de caractères dans un texte. Il évite de comparer caractère par caractère le motif cherché avec un extrait du texte dont la longueur est celle du motif, extrait que l’on décale de 1 en 1 dans le texte jusqu’à trouver le motif ou jusqu’à la fin du texte si le motif n’est pas présent.

$\bold{6}$

Une définition de la fonction $\text{arret\textunderscore essai2}$ est la suivante :

$\text{def arret\textunderscore essai2(programme):}$

$\text{return not recherche('while', programme)}$

$\bold{7}$

Il existe une autre situation que celle d’une boucle while qui peut provoquer la non terminaison d’un programme. Il s’agit d’un programme faisant appel à une fonction récursive dans laquelle aucun cas de base n’est défini, ou dans laquelle le cas de base n’est jamais rencontré.

Voici un exemple :

$\text{programme\textunderscore infini = ’’ ’’ ’’}$ $\text{def exemple\textunderscore fonction():}$

$\text{ exemple\textunderscore fonction()}$

$\text{exemple\textunderscore fonction()}$

$\text{’’ ’’ ’’}$

L’appel $\text{arret\textunderscore essai2(programme\textunderscore infini)}$ renvoie True car la fonction ne trouve pas la chaîne while dans le programme. Pourtant, $\text{programme\textunderscore infini}$ ne termine pas.

À l’inverse, l’appel $\text{arret\textunderscore essai2(programme3)}$ renvoie False car la fonction trouve la chaîne while dans $\text{programme3}$. Pourtant, $\text{programme3}$ termine.

$\bold{8}$

Une définition de la fonction $\text{terminaison\textunderscore inverse}$ est la suivante :

$\text{def terminaison\textunderscore inverse(programme):}$

$\text{if arret(programme):}$

$\text{ boucle\textunderscore infinie()}$

$\bold{9}$

Si le programme $\text{programme\textunderscore paradoxal}$ termine, alors l’appel $\text{terminaison\textunderscore inverse(programme\textunderscore paradoxal)}$ ne termine pas, et donc $\text{programme\textunderscore paradoxal}$ ne termine pas.

Si le programme $\text{programme\textunderscore paradoxal}$ ne termine pas, alors l’appel $\text{terminaison\textunderscore inverse(programme\textunderscore paradoxal)}$ termine, et donc $\text{programme\textunderscore paradoxal}$ termine.

$\bold{10}$

Un programme ne peut pas à la fois terminer et ne pas terminer. On a donc prouvé par l’absurde que la fonction $\text{arret}$ recherchée ne peut pas exister.

$\bold{11}$

Ce résultat ne s’explique pas par les limitations de Python. Nous aurions pu démontrer par l’absurde l’inexistence de la fonction $\text{arret}$ avec un autre langage.

EXERCICE 2 (6 points)

PARTIE A

$\bold{1}$

Chaque caractère est codé en « ASCII latin1 » sur 1 octet. La variable $\text{txt}$ compte 10 caractères. Si celle-ci est codée en ASCII latin1, sa longueur est alors de 10 octets, soit $10 \times 8 = 80$ bits.

$\bold{2}$

Le codage de la chaîne de caractères stockés dans la variable $\text{txt}$ est le suivant : $\text{53 49 58 20 41 4E 41 4E 41 53}$

$\bold{3}$

Le tableau d’occurrences associé à la chaîne de caractères stockés dans la variable $\text{txt}$ est le suivant :

Symbole

A

I

N

S

X

SP

Nombre d'occurrences

3

1

2

2

1

1

$\bold{4}$

La somme des nombres d’occurrences correspond au nombre total de caractères de la chaîne stockée dans $\text{txt}$, autrement dit, la taille de ce texte.

$\bold{5}$

Une définition possible de la fonction $\text{occurrence}$ est la suivante :

$\text{def occurrence(texte):}$

$\text{dico = {}}$

$\text{for lettre in texte:}$

$\text{ if lettre in dico:}$

$\text{ dico[lettre] = dico[lettre] + 1}$

$\text{ else:}$

$\text{ dico[lettre] = 1}$

$\text{return dico}$

$\bold{6}$

Étape 1 :

Arbre de Huffman

Étape 2 :

Arbre de Huffman

Étape 3 :

Arbre de Huffman

Étape 4 :

Arbre de Huffman

Étape 5 :

Arbre de Huffman

Étape 6 :

Arbre de Huffman

$\bold{7}$

Le poids à la racine de l’arbre obtenu correspond à la taille du texte.

$\bold{8}$

Il faudra procéder à un parcours en profondeur. À chaque feuille atteinte, c’est-à-dire ici chaque symbole, on associera le codage déduit du parcours suivi jusqu’à elle.

$\bold{9}$

La table de codage pour la chaîne de caractères contenus dans la variable $\text{txt}$ est la suivante :

Symbole

I

SP

X

N

S

A

Code

1010

1011

100

00

01

11

REMARQUE :

Selon l’ordre choisi à l’étape a) de la question 6 (I SP X N S A, X SP I S N A, …), on n’obtient pas forcément le même codage. En revanche, on utilise le même nombre de bits pour coder les symboles.

$\bold{10}$

On constate que le nombre de bits utilisés pour coder les caractères n’est pas toujours le même. Par exemple :

  • il faut 4 bits pour coder le caractère « I » ;
  • il faut 3 bits pour coder le caractère « X » ;
  • il faut 2 bits pour coder le caractère « A ».

Le code Huffman est donc à longueur variable.

$\bold{11}$

Le codage de la chaîne de caractères contenue dans la variable $\text{txt}$ est le suivant :

$\text{01 1010 100 1011 11 00 11 00 11 01}$

$\bold{12}$

L’encombrement initial avec un codage en ASCII latin 1 était de 80 bits.

L’encombrement final avec le codage de Huffman est de 25 bits.

Le taux de compression est donc de :

$\dfrac{80 - 25}{80} = \dfrac{55}{80} = 0,6875$

Soit environ 69 %, taux qui se situe bien dans la fourchette annoncée.

EXERCICE 3

bannière attention

Attention

Il faut encadrer de guillemets les champs contenant un tiret « - » dans les requêtes SQL demandées dans les questions de cet exercice. Dans le cas contraire, le tiret serait interprété comme une opération de soustraction.

$\bold{1}$

Il ne faut retenir que les enregistrements dont la date de fin de la location n’est pas renseignée.

$\text{SELECT "id-kimono"}$ $\text{FROM location}$ $\text{WHERE fin = ' ';}$

$\bold{2}$

Il faut compter le nombre de kimonos, donc appliquer $\text{COUNT}$ à $\text{"id-kimono"}$.

$\text{SELECT COUNT("id-kimono")}$ $\text{FROM kimono}$ $\text{WHERE "taille-kimono" = 130;}$

$\bold{3}$

La requête s’appuie sur des informations stockées dans 2 tables : $\text{adherent}$ et $\text{location}$. Une jointure est donc nécessaire. On veille à ne sélectionner que l’enregistrement de la table $\text{location}$ dont la date de fin n’est pas renseignée puisque l’on ne s’intéresse qu’à la location en cours du kimono 42.

$\text{SELECT nom, prenom}$ $\text{FROM adherent}$ $\text{JOIN location ON adherent."numero-licence" = location."numero-licence"}$ $\text{WHERE "id-kimono" = 42 AND fin = ' ';}$

$\bold{4}$

$\text{UPDATE adherent}$ $\text{SET "taille-adherent" = "taille-adherent" + 10}$ $\text{WHERE "taille-adherent" < 160;}$

$\bold{5}$

Il faut veiller à supprimer en premier lieu les enregistrements dans les tables faisant appel à la clé étrangère $\text{"id-kimono"}$ de valeur 25 (donc dans la table $\text{location}$), puis à supprimer le kimono n°25 dans la table $\text{kimono}$.

$\text{DELETE FROM location}$ $\text{WHERE "id-kimono" = 25;}$

$\text{DELETE FROM kimono}$ $\text{WHERE "id-kimono" = 25;}$

PARTIE B

$\bold{6}$

$\text{M12102021NIRRE01}$

$\bold{7}$

Date de naissance : 23 septembre 1974

Nom possible : MARTINEZ

$\bold{8}$

L’expression $\text{tab\textunderscore adherents[1]['prenom']}$ permet de récupérer la valeur du champ $\text{prenom}$ du second élément (le premier ayant l’index 0). Elle correspond donc à la valeur $\text{"STEPHANIE"}$.

$\bold{9}$

La valeur $\text{"F03071997DUPON01"}$ correspond au numéro d’adhérent du premier élément du dictionnaire. L’expression permettant de l’obtenir est donc :

$\text{tab\textunderscore adherents[0]['numero-licence']}$

$\bold{10}$

$\text{def nombre\textunderscore adherents(table, annee):}$

$\text{compteur = 0}$

$\text{for adherent in table:}$

$\text{ if adherent['annee'] == annee:}$

$\text{ compteur += 1}$

$\text{return compteur}$

$\bold{11}$

Sachant qu’il peut y avoir plusieurs adhérents nés la même année, la fonction demandée doit renvoyer une liste.

$\text{def adherent\textunderscore plus\textunderscore age(table):}$

$\text{liste = []}$

$\text{annee\textunderscore minimum = 2024}$

$\text{for adherent in table:}$

$\text{ if adherent['annee'] < annee\textunderscore minimum:}$

$\text{ annee\textunderscore minimum = adherent['annee']}$

$\text{ liste = [adherent]}$

$\text{ elif adherent['annee'] == annee\textunderscore minimum:}$

$\text{ liste.append(adherent)}$

$\text{return liste}$

$\bold{12}$

$\text{def verification\textunderscore licence(adherent):}$

$\text{if extraire(adherent['numero-licence'], 0, 1) != adherent['sexe']:}$

$\text{ return False}$

$\text{if extraire(adherent['numero-licence'], 1, 3) != adherent['jour']:}$

$\text{ return False}$

$\text{if extraire(adherent['numero-licence'], 3, 5) != adherent['mois']:}$

$\text{ return False}$

$\text{if extraire(adherent['numero-licence'], 5, 9) != adherent['annee']:}$

$\text{ return False}$

$\text{if extraire(adherent['numero-licence'], 9, 14) != extraire(adherent['nom'], 0, 5):}$

$\text{ return False}$

$\text{return True}$