Wadifa InfoEmploi public au Maroc ع

Modèle de concours : CNC 2015 Informatique (MP/PSI/TSI) — Concours National Commun

🏢 Concours National Commun (CNC) — CPGE 👤 Concours d'accès aux écoles d'ingénieurs 🎯 Informatique 📅 2015 👁️ 33 vues

⬇️ Télécharger le PDF Adresse permanente : https://www.wadifa-info.com/fr/modele-concours/1743/modele-de-concours-cnc-2015-informatique-mp-psi-tsi-concours-national-commun

En bref

Ce document est une ancienne épreuve écrite du concours de Concours d'accès aux écoles d'ingénieurs organisé par Concours National Commun (CNC) — CPGE (2015), publiée sur Wadifa Info en consultation et téléchargement PDF gratuits, avec une correction proposée.

Organisme
Concours National Commun (CNC) — CPGE
Grade
Concours d'accès aux écoles d'ingénieurs
Spécialité
Informatique
Année
2015
Pages
8
Langue des questions
français
Correction
correction proposée disponible sur cette page
Sujet officiel de l'épreuve de Informatique du Concours National Commun (CNC) 2015 d'admission dans les établissements de formation d'ingénieurs et assimilés, pour les élèves des classes préparatoires (CPGE) de la filière MP/PSI/TSI. Ce modèle contient les 8 pages de l'énoncé original. Les autres épreuves et sessions du CNC sont aussi disponibles sur le site.
📝 Texte des questions (extrait automatiquement des pages scannées)

Ce texte est extrait automatiquement des images de l'épreuve et peut contenir des erreurs de lecture — les images ci-dessus font foi.

— صفحة 1 —
ROYAUME DU MAROC
‏المملكة المغربية‎

Ministère de l'Enseignement Supérieur,
de la Formation des Cadres et de la Recherche Scientifique

Présidence du Concours National Commun 2015
Ecole Nationale Supérieure d’Electricité et de Mécanique
Po 8 ‏ب‎

CONCOURS NATIONAL COMMUN
d'Admission dans les Établissements de Formation
d'Ingénieurs et Établissements Assimilés

Édition 2015

ÉPREUVE D'INFORMATIQUE

Filières : MP/PSI/TSI

Durée 2 heures

Cette épreuve comporte 07 pages au format A4, en plus de cette page de garde
L'usage de la calculatrice est interdit

Page de garde

نماذج المباريات من موقع وظيفة إنفو ‎wadifa-info.com‏

— صفحة 2 —
Épreuve d'informatique — Session 2015 — Filière MP/ PSI/ TSI
Concours National Commun

Les candidats sont informés que la précision des raisonnements algorithmiques ainsi que le soin
apporté à la rédaction et à la présentation des copies seront des éléments pris en compte dans la
notation. Il convient en particulier de rappeler avec précision les références des questions
abordées. Si, au cours de l'épreuve, un candidat repère ce qui peut lui sembler être une erreur
d'énoncé, il le signale sur sa copie et poursuit sa composition en expliquant les raisons des
initiatives qu'il est amené à prendre.

Remarques générales :
— L'épreuve se compose de deux exercices et d'un problème.
— Toutes les instructions et les fonctions demandées seront écrites en langage Python.
— Les questions non traitées peuvent être admises pour aborder les questions ultérieures.
— Toute fonction peut être décomposée, si nécessaire, en plusieurs fonctions.

Exercice 1. Thème : base de données

Nous allons nous intéresser à la gestion d'une compagnie de trains de marchandises en nous
limitant à la gestions des trains. La base de données permettant la gestion des différents trains de
cette compagnie sera constituée de 3 tables : TRAIN, TRAJET, TYPE.

La description de ces tables est la suivante :

TRAIN TRAJET TYPE
immatriculation : entier num_trajet : entier id : entier
gare_attache : texte immatriculation : entier nom : texte
id : entier ville_dep : texte nb_place : entier

ville_arr : texte
heure_dep : date

Une clé étrangère id est placée sur la table TRAIN et mise en relation avec la clé primaire id de la
table TYPE.
Une clé étrangère immatriculation est placée sur la table TRAJET et mise en relation avec la clé
primaire immatriculation de la table TRAIN.
Une clé primaire num_trajet est placée sur la table TRAJET.
Autre représentation :
TRAIN (immatriculation, gare_attache, id)
Exemple : (2034, "Fez", 2)
TRAJET (num_trajet, immatriculation, ville_dep, ville_arr, heure_dep, heure_arr)

Exemple : (789,2034 "Rabat", "Casablanca", "09h00", "10h20")
TYPE (id, nom, nb_place)

Exemple : (2, "TNR", 440)

نماذج المباريات من موقع وظيفة إنفو ‎wadifa-info.com‏

— صفحة 3 —
Épreuve d'informatique — Session 2015 — Filière MP/ PSI/ TSI
Concours National Commun

Dans la représentation précédente les clefs principales sont en caractères gras et les clefs
secondaires en italique et soulignés.

Vous pouvez utiliser le système de base de données que vous souhaitez. Cette base de données
pourra être de type SQLite ou MySQL ou PostgreSQL etc.

Si vous utilisez une base de données SQLite, le fichier « gestion_trains.sqlite » représentant cette
base de données se trouvera dans le même répertoire que vos programmes Python (sous C:\CNC\)
de cette compagnie ferroviaire.

Dans cet exercice la base de données est déjà créée : tables avec leurs contenus.

Question 1 :

Écrire une requête SQL donnant comme résultat l'heure de départ, l'heure d'arrivée et
l'identifiant de tous les trains au départ de la ville de Fez.
Question 2 :

Modifier la requête précédente afin d'afficher, en plus des informations demandées, la gare
d'attache de tous les trains toujours au départ de la ville de Fez. Attention on ne veut pas de
doublon.

Question 3 :

Écrire une requête SQL donnant comme résultat le nombre de trajets au départ de Rabat
par type de train.
Question 4 :

Écrire une requête SQL donnant le nom et la gare de départ de tous les trains dont l'heure
de départ est comprise entre 7h et 13h.
Question 5 :

Écrire en Python le programme complet qui affichera le résultat de l'une des requêtes
correspondant aux quatre premières questions. Vous pouvez utiliser le système de base de
données que vous voulez, la création et le contenu des trois tables sont créés par défaut.

Exercice 2. Thème : calcul scientifique

On souhaite résoudre l'équation différentielle :

dia Æ E
dé 2° à 2

avec : a=-3.0 et b=-1.0

Question 6 :

La fonction odeint() du module scipy.integrate a pour syntaxe :

scipy.integrate.odeint (fonction f, valeur initiale en a, subdivision de [a, b]).

La fonction odeint() ne permet de résoudre que des équations d'ordre 1.

Expliquer comment on peut transformer l'équation (E) en une équation du premier ordre.

نماذج المباريات من موقع وظيفة إنفو ‎wadifa-info.com‏

— صفحة 4 —
Épreuve d'informatique — Session 2015 — Filière MP/ PSI/ TSI
Concours National Commun

Question 7 :
Le principe d'utilisation de la fonction odeint() permet d'obtenir une estimation numérique de la

solution du problème de Cauchy : { ()=F(7 (6,1)

Écrire en Python une fonction F(z,t) qui prend en argument un vecteur colonne z composé
de deux éléments, la variable t et qui retourne un tableau (array du module numpy) composé
également de deux éléments.

La librairie numpy est très riche en fonctionnalités (np.arrange(), np.linspace(), np.array(),
np.ones{(), np.sin(), np.histogram(), np.concatenate(), …)

Lors de l'implémentation de la fonction F(), préciser bien à quoi correspondent les différents
paramètres mis en œuvre.

Question 8 :

On souhaite avoir la représentation suivante de cette équation différentielle :

Tirguel ess
900 + 5 BR

Pour la courbe représentée dans la "Figure 1" le nombre d'échantillons générés est égal à 100.
Implémenter dans le langage Python, en utilisant la fonction odeint() citée précédemment,

la formule (E) générant le graphique de la "Figure 1

Attention vous devez pour les valeurs initiales qui vous manquent estimer leurs valeurs en

observant la courbe de cette figure.

La librairie matplotlib permet de tracer toutes sortes de graphiques notamment avec la sous-

librairie matplotlib.pyplot.

نماذج المباريات من موقع وظيفة إنفو ‎wadifa-info.com‏

— صفحة 5 —
Épreuve d'informatique — Session 2015 — Filière MP/ PSI/ TSI
Concours National Commun

Problème : Gestion des expressions postfixées

Remarque :

Les deux parties de ce problème sont indépendantes. La deuxième partie peut être faite en prenant
les résultats de la première partie.

Par définition une expression est une suite de nombres associée à un ensemble d'opérateurs avec
éventuellement un jeu de parenthèses ouvrantes et fermantes.

L'objet de ce problème est de gérer des expressions post fixées, expressions algébriques
constituées d'éléments appelés opérandes et d'opérateurs. La position de l'opérateur par rapport
aux opérandes indique le type d'expressions algébriques : infixées, préfixées, postfixées. La
notation préfixée est souvent appelée notation polonaise car inventée par le mathématicien Jan
Lukasiewicz et par opposition la notation postfixée est appelée notation polonaise inverse.

Il n'y aura aucune priorité particulière entre les différents opérateurs.

Exemple :

Notation infixée : (1+5) *6

Notation préfixée : + 1 6 *

Notation postfixée : 1 5 + 6 *

Autre exemple :

L'écriture postfixée de (3+2) * 5 est 3 2+ 5 * et celle de 3+(2 * 5) est 32 5 * +.

Question 9 :
Citer un intérêt d'utiliser la notation postfixée plutôt que la notation infixée.

Première partie

Afin de réaliser le traitement, c'est-à-dire le calcul d'une expression postfixée nous avons besoin
d'un composant, une file d'attente, une "pile" de type FIFO (First In First Out).

Par définition une pile sera implémentée à l'aide d'une liste, le sommet de la pile sera toujours
situé en début de liste. Vous devez dans cette première partie définir différentes fonctions
capables d'utiliser une telle file d'attente qui n'aura pas de limite.

Afin que la pile puisse fonctionner correctement il faudra vérifier lors de la sortie d'un élément,
que la file n'est pas vide. L'exception Pile VideException est définie par défaut.

Pour l'implémentation de votre Pile vous devez utiliser les fonctions fournies dans l'annexe.

Question 10 :

Écrire une fonction initPile() afin d'initialiser une pile.

Question 11 :
Écrire la fonction estVide(pile) qui indique si une pile est vide.

Question 12 :
Écrire la fonction empiler(pile, elem) qui ajoutera à la file d'attente l'élément e/em.

نماذج المباريات من موقع وظيفة إنفو ‎wadifa-info.com‏

— صفحة 6 —
نماذج المباريات من موقع وظيفة إنفو

Concours National Commun

Question 13 :

Écrire la fonction depiler(pile) qui supprimera de la file d'attente le dernier élément entré
et retournera cet élément.
Question 14 :

Écrire la fonction valeurSommet(pile) qui affichera l'élément se trouvant au sommet de la
file d'attente. Cette fonction ne supprimera pas cet élément.
Question 15 :

Écrire la fonction hauteur(pile) qui affichera le nombre d'éléments se trouvant dans la pile.

Deuxième partie :

Principe de l'évaluation. Pour calculer une expression arithmétique codée en postfixée, il suffit :
*  d'empiler les entiers successifs que l'on rencontre ;
* lorsque l'on détecte un opérateur, il faut
dépiler les 2 derniers entiers ;
leur appliquer l'opérateur ;
٠ empiler le résultat ;
* enfin, lorsque l'on rencontre un point, le résultat du calcul doit être dépilé puis affiché.

Question 16 :
On souhaite tester si une expression est bien un nombre. La fonction estEntier() donnera comme
résultat une valeur booléenne : True si l'expression est un nombre entier et False sinon. Attention,
il n'est pas possible d'utiliser la fonction isinstance(). La fonction estEntier() sera de style récursif.
›››estEntier ('12')
True
›››estEntier (12)
True
›››estEntier ('la4')
False
Question 17 :

Définir la fonction eval() qui sera constituée de trois paramètres, un opérateur (un
caractère), suivi de deux opérandes (deux nombres entiers). Deux exceptions sont définies par
défaut. L'exception OpNonValideException sera levée lorsqu'un opérateur ne sera pas valide et
l'exception ArgNonValideException si un opérande est non valide. La liste des opérateurs utilisés
est la suivante : +,-,*,/,. (le caractère point).

3

ArgNonValideException
Question 18 :
Définir la fonction evalue() qui aura comme arguments, l'expression postfixée à analyser.
Cette fonction retournera la valeur du calcul correspondant à cette expression.
11

wadifa-info.com

— صفحة 7 —
Épreuve d'informatique — Session 2015 — Filière MP/ PSI/ TSI
Concours National Commun

Question 19 :

On s'intéresse à présent aux expressions infixées, comme par exemple : 1+3*4 qui sera traduite par
l'expression ['1' +" "3," *""4"""]. Les parenthèses sont souvent utilisées afin de donner le sens que
l'on souhaite aux différents calculs. Par exemple (1+3)*4 et 1+(3*4) donneront deux résultats
différents. Dans cette question une expression pourra utiliser différents niveaux d'imbrication de
parenthèses, comme par exemple (1+(5*(6+2))).

Définir la fonction estBienParenthesee() qui aura une expression (une liste de caractères)
comme paramètre et retournera comme valeur une chaîne de caractère Expression mal
parenthésée ou Expression bien parenthésée.

Question 20 :

Dans cette question les expressions infixées n'auront pas de parenthèses.

Définir la fonction transinfix() qui aura comme paramètre une expression infixée qui
retournera une expression postfixée. On mettra en œuvre un mécanisme d'exception pour tester si
l'expression fournie est vide ou mal formée.

[ Li 8 Li ‏ع‎ ' 4 LE F Li + Li * ' 3 1 x" y ' 1 LE A LE + 1 A ' : LE ]
Question 21 :

En se limitant à un seul niveau de parenthèses, expliquez comment vous feriez pour transformer
une expression infixée en une expression postfixée. On ne demande pas du code mais le
mécanisme à mettre en œuvre.
›››transiInfixilSeulHiveau([l'(', '1', "+, 121, 1) 1, TET, LOT, TA "])

Question 22 :

Il y a différentes manières d'exprimer une expression postfixée. Les deux expressions suivantes
sont totalement identiques, formel :['8', '4', + 3*1 - .'[ et
forme2 “14, 3 4 8 +, a ‏بادا‎ A
Définir la fonction transTotal() qui transforme une expression postfixée de type forme1 en

une expression postfixée de type forme2.
›››transTotal (expr)

Question 23 :

Modifier la fonction précédente afin que le paramètre passé à transTotal() soit non pas une
expression postfixée de type 1 mais une expression infixée.

›››transTotal(['1', tt, 151, T4t, ‏(["ا 87 تا اا‎

نماذج المباريات من موقع وظيفة إنفو ‎wadifa-info.com‏

— صفحة 8 —
Épreuve d'informatique — Session 2015 — Filière MP/ PSI/ TSI
Concours National Commun

ANNEXE

str(p) : Retourne une chaîne contenant une représentation bien imprimable d'un objet ‏.م‎ Pour les
chaînes, cela renvoie la chaîne elle-même.

Opérations sur les listes :

Soit Lun élément de type list. La liste des méthodes des objets de type list est :

list.append(x) Ajoute un élément à la fin de la liste.

list.extend(L) Étend la liste en y ajoutant tous les éléments de la liste fournie.

list.insert(i, x) Insère un élément à la position indiquée. Le premier argument est la position de
l'élément courant avant lequel l'insertion doit s'effectuer.

list.remove(x) Supprime de la liste le premier élément dont la valeur est x. Une exception est levée
s'il n'existe aucun élément avec cette valeur.

list.index(x) Retourne la position du premier élément de la liste ayant la valeur x. Une exception
est levée s'il n'existe aucun élément avec cette valeur.

list.count(x) Retourne le nombre d'éléments ayant la valeur x dans la liste.

list.sort(emp=None, key=None, reverse=False) Trie les éléments de la liste.

list.reverse() Inverse l'ordre des éléments de la liste en place.

Figure 1 exercice 2

0.3

0.2

0.1

0.0

نماذج المباريات من موقع وظيفة إنفو ‎wadifa-info.com‏

✅ Correction proposée

Il s'agit d'une correction proposée, rédigée par l'équipe wadifa-info pour vous aider à comprendre la méthode — ce n'est pas un corrigé officiel de l'administration organisatrice.

Ce sujet est l'épreuve d'informatique du Concours National Commun (CNC) 2015, commune aux filières MP, PSI et TSI des classes préparatoires, pour l'admission dans les écoles d'ingénieurs marocaines (présidence : ENSEM). Durée : 2 heures, calculatrice interdite, tout en Python. Il comporte deux exercices et un problème : bases de données (SQL), calcul scientifique (équation différentielle avec odeint) et un problème sur les expressions postfixées (piles, évaluation, conversion infixe → postfixe). Voici une correction méthodologique proposée.

💡 Avant de commencer : les exercices 1 et 2 sont très classiques et rapportent vite : traitez-les en 45 minutes maximum. Dans le problème, les questions 10 à 18 (pile + évaluation) sont le cœur du barème ; les questions 20 à 23 contiennent des exemples ambigus, voire incohérents : l'énoncé vous autorise à le signaler sur la copie — faites-le en une phrase, puis donnez une fonction cohérente avec votre convention.

Exercice 1 — Base de données (trains de marchandises)

Schéma : TRAIN(immatriculation, gare_attache, id), TRAJET(num_trajet, immatriculation, ville_dep, ville_arr, heure_dep, heure_arr), TYPE(id, nom, nb_place). L'« identifiant » d'un train est son immatriculation ; le « nom » d'un train est le nom de son TYPE (ex. "TNR").

Question 1

SELECT heure_dep, heure_arr, immatriculation FROM TRAJET WHERE ville_dep = 'Fez';

Toutes les informations sont dans TRAJET : aucune jointure n'est nécessaire.

Question 2

SELECT DISTINCT tj.heure_dep, tj.heure_arr, tj.immatriculation, tr.gare_attache
FROM TRAJET tj JOIN TRAIN tr ON tj.immatriculation = tr.immatriculation
WHERE tj.ville_dep = 'Fez';

La gare d'attache est dans TRAIN : jointure sur la clé étrangère immatriculation. DISTINCT supprime les doublons demandés.

Question 3

SELECT ty.id, ty.nom, COUNT(*) AS nb_trajets
FROM TRAJET tj JOIN TRAIN tr ON tj.immatriculation = tr.immatriculation
JOIN TYPE ty ON tr.id = ty.id
WHERE tj.ville_dep = 'Rabat'
GROUP BY ty.id, ty.nom;

Double jointure TRAJET → TRAIN → TYPE, filtre avant regroupement (WHERE), puis agrégat COUNT par type.

Question 4

SELECT DISTINCT ty.nom, tj.ville_dep
FROM TRAJET tj JOIN TRAIN tr ON tj.immatriculation = tr.immatriculation
JOIN TYPE ty ON tr.id = ty.id
WHERE tj.heure_dep BETWEEN '07h00' AND '13h00';

Les heures de l'exemple sont des chaînes du type "09h00" : sur deux chiffres, l'ordre alphabétique coïncide avec l'ordre chronologique, donc BETWEEN fonctionne. Si heure_dep est un vrai type TIME, on écrit BETWEEN '07:00:00' AND '13:00:00'. La « gare de départ » est ville_dep (on peut aussi proposer gare_attache en le précisant).

Question 5 — programme Python complet (SQLite)

import sqlite3
connexion = sqlite3.connect('C:/CNC/gestion_trains.sqlite')
curseur = connexion.cursor()
curseur.execute("SELECT heure_dep, heure_arr, immatriculation FROM TRAJET WHERE ville_dep = 'Fez'")
for ligne in curseur.fetchall():
    print(ligne)
connexion.close()

Les étapes attendues : connexion, curseur, execute, fetchall, affichage, fermeture.

Exercice 2 — Calcul scientifique

Équation (E) : y'' = a·y + b·y', avec a = −3,0 et b = −1,0, soit y'' + y' + 3y = 0.

Question 6 — passage au premier ordre

On pose le vecteur Z(t) = (y(t), y'(t)). Alors Z'(t) = (y'(t), a·y(t) + b·y'(t)) = F(Z(t), t). L'équation scalaire d'ordre 2 devient un système différentiel d'ordre 1 de dimension 2, que odeint sait intégrer. Il faut alors deux conditions initiales : y(t0) et y'(t0).

Question 7 — la fonction F

import numpy as np
a, b = -3.0, -1.0
def F(z, t):
    # z[0] = y(t), z[1] = y'(t) ; t : instant (non utilisé, l'équation est autonome)
    return np.array([z[1], a*z[0] + b*z[1]])

Paramètres : z est l'état courant (position y et dérivée y'), t le temps exigé par la signature de odeint ; la valeur retournée est la dérivée de l'état, (y', y'').

Question 8 — tracé de la Figure 1

Lecture de la figure : t varie de 0 à 5, avec 100 échantillons ; la courbe part de y(0) ≈ 0,05 en montant fortement, atteint un maximum ≈ 0,30 vers t ≈ 0,7, un minimum ≈ −0,115 vers t ≈ 2,6, puis ≈ 0,045 vers t ≈ 4,5.

Estimation de y'(0) : la solution exacte est y(t) = e−t/2(A cos ωt + B sin ωt) avec ω = √11/2 ≈ 1,66 (racines de r2 + r + 3 = 0). Avec A = y(0) = 0,05 et y'(0) ≈ 0,7, on obtient un maximum 0,297 à t ≈ 0,70, un minimum −0,115 à t ≈ 2,60 et y(5) ≈ 0,03 : c'est exactement la figure. Donc Y0 = [0.05, 0.7] (une valeur proche, lue graphiquement, est acceptée).

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
a, b = -3.0, -1.0
def F(z, t):
    return np.array([z[1], a*z[0] + b*z[1]])
t = np.linspace(0, 5, 100)    # 100 échantillons sur [0, 5]
z0 = [0.05, 0.7]    # y(0), y'(0) estimés sur la figure
sol = odeint(F, z0, t)    # tableau 100 x 2 : colonnes y et y'
plt.plot(t, sol[:, 0])
plt.xlabel('t')
plt.ylabel('y')
plt.show()

Problème — Gestion des expressions postfixées

Question 9

La notation postfixée n'a besoin ni de parenthèses ni de règles de priorité : une expression s'évalue en un seul parcours de gauche à droite avec une pile, en temps linéaire. C'est donc plus simple à analyser et à calculer pour une machine (principe des calculatrices HP et des machines à pile).

Remarque sur l'énoncé

L'énoncé parle d'une « file d'attente FIFO » mais décrit en réalité une pile LIFO (on dépile « le dernier élément entré »). On implémente une pile dont le sommet est en tête de liste, comme demandé. Les exceptions « définies par défaut » s'écrivent par exemple : class PileVideException(Exception): pass.

Questions 10 à 15 — primitives de pile

def initPile():
    return []

def estVide(pile):
    return len(pile) == 0

def empiler(pile, elem):
    pile.insert(0, elem)    # le sommet est en tête

def depiler(pile):
    if estVide(pile):
        raise PileVideException()
    x = pile[0]
    del pile[0]
    return x

def valeurSommet(pile):
    if estVide(pile):
        raise PileVideException()
    print(pile[0])
    return pile[0]

def hauteur(pile):
    print(len(pile))
    return len(pile)

Points notés : la vérification de pile vide avant de dépiler (et avant de lire le sommet), et le fait que valeurSommet ne modifie pas la pile. Coût : insert(0, …) et del pile[0] sont en O(n) ; mettre le sommet en fin de liste (append/pop) serait en O(1), mais l'énoncé impose le début de liste.

Question 16 — estEntier (récursive, sans isinstance)

def estEntier(x):
    s = str(x)    # accepte 12 comme '12'
    if s == '':
        return False
    if len(s) == 1:
        return s in '0123456789'
    return s[0] in '0123456789' and estEntier(s[1:])

Cas de base : un seul caractère, qui doit être un chiffre ; cas récursif : premier caractère chiffre ET le reste est un entier. On obtient bien True pour '12' et 12, False pour '1a4'.

Question 17 — eval(op, a, b)

def eval(op, a, b):    # masque la fonction native eval, nom imposé
    if op not in ['+', '-', '*', '/', '.']:
        raise OpNonValideException()
    if type(a) != int or type(b) != int:
        raise ArgNonValideException()
    if op == '+': return a + b
    if op == '-': return a - b
    if op == '*': return a * b
    if op == '/':
        if b == 0: raise ArgNonValideException()
        return a // b    # opérandes entiers
    return a    # '.' : fin d'expression, pas de calcul

eval('+', 1, 2) renvoie 3 ; eval('+', '1', 2) lève ArgNonValideException car '1' est une chaîne. La division par zéro est traitée comme un opérande non valide.

Question 18 — evalue(expr)

def evalue(expr):
    p = initPile()
    for x in expr:
        if x == '.':
            return depiler(p)
        if estEntier(x):
            empiler(p, int(x))
        else:
            b = depiler(p)    # opérande de droite (sommet)
            a = depiler(p)    # opérande de gauche
            empiler(p, eval(x, a, b))
    raise ArgNonValideException()    # pas de point final

evalue([7, 4, '+', '.']) : on empile 7 puis 4, '+' dépile 4 et 7 et empile 11, le point dépile et renvoie 11. Attention à l'ordre : le premier dépilé est l'opérande de droite (important pour − et /). Une expression mal formée (opérateur sans deux opérandes) déclenche PileVideException.

Question 19 — estBienParenthesee

def estBienParenthesee(expr):
    n = 0    # nombre de parenthèses ouvertes non fermées
    for c in expr:
        if c == '(':
            n = n + 1
        elif c == ')':
            n = n - 1
            if n < 0:
                return 'Expression mal parenthésée'
    if n == 0:
        return 'Expression bien parenthésée'
    return 'Expression mal parenthésée'

Deux conditions : le compteur ne devient jamais négatif (pas de ')' avant son '(') et il vaut 0 à la fin. On peut aussi empiler chaque '(' et dépiler à chaque ')' avec les fonctions de la première partie : c'est le même raisonnement.

Question 20 — transInfix (sans parenthèses)

L'exemple 1+3*4+8 → ['8','4','+','3','*','1','+','.'] montre la convention de l'énoncé : sans priorité, l'expression est lue de droite à gauche (résultat 1+(3·(4+8)) = 37). Il suffit donc de retourner l'expression puis de la convertir de gauche à droite : premier opérande, puis chaque couple (opérateur, opérande) donne « opérande, opérateur ».

class ExpressionException(Exception): pass

def transInfix(expr):
    if len(expr) < 2 or expr[-1] != '.':
        raise ExpressionException('expression vide')
    r = expr[:-1]
    r.reverse()
    if len(r) % 2 == 0:
        raise ExpressionException('expression mal formée')
    for i in range(len(r)):    # alternance opérande / opérateur
        if (i % 2 == 0) != estEntier(r[i]):
            raise ExpressionException('expression mal formée')
    res = [r[0]]
    for i in range(1, len(r), 2):
        res.append(r[i+1])
        res.append(r[i])
    res.append('.')
    return res

Vérification : transInfix(['1','+','3','*','4','+','8','.']) renvoie bien ['8','4','+','3','*','1','+','.'], et evalue de ce résultat donne 37. Remarque à écrire sur la copie : retourner l'expression permute les opérandes de − et /, ce qui n'est sans effet que pour + et * (les seuls opérateurs de l'exemple).

Question 21 — un seul niveau de parenthèses (mécanisme)

L'exemple ['(','1','+','2',')','*','4','.'] → ['1','2','+','4','*','.'] se traite par un parcours de gauche à droite avec une pile d'opérateurs (algorithme de Dijkstra sans priorités) :

  • un opérande est recopié directement dans la sortie ;
  • une parenthèse ouvrante est empilée ;
  • un opérateur : on dépile vers la sortie l'opérateur éventuellement présent au sommet (tant que ce n'est pas '('), puis on empile le nouvel opérateur ;
  • une parenthèse fermante : on dépile vers la sortie jusqu'à la '(' qu'on supprime ;
  • au point final, on vide la pile dans la sortie et on ajoute '.'.

Autre présentation acceptée : chaque bloc entre parenthèses est converti séparément en postfixé, puis traité comme un seul opérande dans l'expression de niveau supérieur. On vérifie d'abord le parenthésage avec la question 19.

Question 22 — transTotal (forme1 → forme2)

Sur l'exemple, forme1 = ['8','4','+','3','*','1','-','.'] et forme2 = ['1','3','4','8','+','*','-','.'] : forme2 contient les opérandes de forme1 dans l'ordre inverse, puis les opérateurs dans leur ordre d'apparition, puis le point.

def transTotal(expr):
    nombres = []
    operateurs = []
    for x in expr[:-1]:
        if estEntier(x):
            nombres.insert(0, x)    # ordre inversé
        else:
            operateurs.append(x)
    return nombres + operateurs + ['.']

On obtient ['1','3','4','8','+','*','-','.'] sur forme1. Remarque : les deux formes donnent le même résultat pour + et * ; avec − la forme2 calculée par evalue donne 1 − 36 = −35 au lieu de 36 − 1 = 35, l'équivalence « totale » annoncée suppose donc une convention d'ordre des opérandes — à signaler.

Question 23 — transTotal à partir d'une expression infixée

Il suffit de composer : def transTotalInfix(expr): return transTotal(transInfix(expr)) (ou d'appeler transInfix au début de transTotal). Pour ['1','+','3','*','4','+','8','.'], transInfix donne ['8','4','+','3','*','1','+','.'] puis transTotal donne ['1','3','4','8','+','*','+','.'], qui s'évalue bien à 37.

Incohérence de l'énoncé : la sortie imprimée ['8','4','3','1','+','*','+','.'] s'évalue à 8 + 4·(3+1) = 24, pas à 37 : elle ne représente pas la même expression. Elle correspond seulement à « opérandes de l'expression infixée pris à l'envers, puis opérateurs », c'est-à-dire à la fonction transTotal de la question 22 appliquée directement à l'infixe, sans passer par transInfix. Le mieux est de signaler l'écart et de justifier son choix.

💡 À retenir pour le CNC informatique : les points sûrs sont les requêtes SQL (jointures sur clés étrangères, DISTINCT, GROUP BY + COUNT, BETWEEN), le programme sqlite3 complet (connect, cursor, execute, fetchall, close), la réduction d'une EDO d'ordre 2 en système d'ordre 1 pour odeint avec la bonne signature F(z, t) et np.linspace, et les piles (vérifier la pile vide, ordre des opérandes au dépilement, évaluation postfixée). Révisez aussi la récursivité sur les chaînes et le contrôle de parenthésage par compteur ou pile. Face à un exemple incohérent, signalez-le en une phrase et restez cohérent avec votre convention.

Un nouveau sujet de concours chaque jour sur WhatsApp

Questions fréquentes sur ce sujet

Ce sujet est-il téléchargeable gratuitement ?
Oui. La totalité du sujet (8 pages) est consultable et téléchargeable gratuitement, sans inscription ni compte.
Le corrigé est-il inclus ?
Oui. Un corrigé proposé figure sur cette page, sous les pages du sujet : méthode de réponse et éléments attendus, rédigés par l'équipe Wadifa Info.
Quel organisme et quel grade concerne ce sujet ?
Ce sujet provient d'un concours organisé par Concours National Commun (CNC) — CPGE. Il concerne le grade : Concours d'accès aux écoles d'ingénieurs.
De quelle session s'agit-il et dans quelle langue ?
Session : 2015. Les questions sont en français.
Où trouver d'autres sujets du même concours ?
Tous nos sujets de la même famille sont regroupés sur la page Accès aux écoles et instituts supérieurs : /fr/modeles-concours/ecoles-instituts-superieurs. Les sujets y sont classés par session, du plus récent au plus ancien.

Source : concours d'accès aux écoles et instituts supérieurs — document archivé tel que reçu ; l'avis officiel du concours fait foi.

}
Utile ? Envoyez-le à quelqu'un qui cherche
WhatsApp Facebook Telegram

📎 Citer cette page

Journaliste, blogueur, enseignant : copiez la référence ci-dessous et mettez un lien vers cette page.

Adresse permanente : https://www.wadifa-info.com/fr/modele-concours/1743/modele-de-concours-cnc-2015-informatique-mp-psi-tsi-concours-national-commun

📲
Installez Wadifa Info sur votre iPhone : appuyez sur le bouton Partager en bas de Safari, puis sur Sur l'écran d'accueil. Les nouveaux concours, sans passer par le navigateur.