Solution de Triangle de Pascal - Sujet 16 - EP NSI 2025

Moyen Officiel
Python (3.14.0)

Énoncé du problème

Exercice 1

Écrire une fonction moyenne(notes) qui renvoie la moyenne pondérée des résultats contenus dans le tableau notes, non vide, donné en paramètre. Ce tableau contient des couples (note, coefficient) dans lesquels :

  • note est un nombre de type flottant (float) compris entre 0 et 20 ;
  • coefficient est un nombre entier strictement positif.

Ainsi l’expression moyenne([(15.0,2),(9.0,1),(12.0,3)]) devra renvoyer 12.5 comme résultat du calcul suivant :

$$\frac{2 \times 15 + 1 \times 9 + 3 \times 12}{2 + 1 + 3} = 12,5$$

Exercice 2

On cherche à déterminer les valeurs du triangle de Pascal (Figure 1).

Dans le triangle de Pascal, chaque ligne commence et se termine par le nombre 1. Comme l’illustre la Figure 2, on additionne deux valeurs successives d’une ligne pour obtenir la valeur qui se situe sous la deuxième valeur.

[Figure 1 : triangle de Pascal — les six premières lignes du triangle affichées en escalier : 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1]

[Figure 2 : méthode de calcul — le même triangle, sur lequel des flèches montrent que la somme de deux valeurs voisines d’une ligne donne la valeur située sous la seconde d’entre elles : « 1 + 1 » de la deuxième ligne donne le 2 de la troisième ligne, « 3 + 3 » de la quatrième ligne donne le 6 de la cinquième ligne, et « 1 + 4 » de la cinquième ligne donne le 5 de la sixième ligne.]

Compléter les fonctions ligne_suivante et pascal ci-dessous. La fonction ligne_suivante prend en paramètre une liste d’entiers ligne correspondant à une ligne du triangle de Pascal et renvoie la liste correspondant à la ligne suivante du triangle de Pascal. La fonction pascal prend en paramètre un entier n et l’utilise pour construire le triangle de Pascal ayant n+1 lignes sous la forme d’une liste de listes.

def ligne_suivante(ligne):
    '''Renvoie la ligne suivant ligne du triangle de Pascal'''
    ligne_suiv = [...]
    for i in range(...):
        ligne_suiv.append(...)
    ligne_suiv.append(...)
    return ligne_suiv

def pascal(n):
    '''Renvoie le triangle de Pascal de hauteur n'''
    triangle = [ [1] ]
    for k in range(...):
        ligne_k = ...
        triangle.append(ligne_k)
    return triangle

Exemples :

>>> ligne_suivante([1, 3, 3, 1])
[1, 4, 6, 4, 1]
>>> pascal(2)
[[1], [1, 1], [1, 2, 1]]
>>> pascal(3)
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]]

Les contraintes ci-dessous sont ajoutées par la plateforme et ne font pas partie du sujet.

Exercice 1

Contraintes :

  • 1 <= len(notes) <= 10^4
  • chaque élément de notes est un couple (note, coefficient)
  • note est un flottant tel que 0 <= note <= 20
  • coefficient est un entier tel que 1 <= coefficient <= 10^3
  • notes est garanti non vide

Exercice 2

Contraintes :

  • 0 <= n <= 100
  • pascal(n) renvoie une liste de n + 1 listes ; pascal(0) renvoie [[1]]
  • ligne_suivante(ligne) reçoit une liste non vide d’entiers correspondant à une ligne du triangle de Pascal, et renvoie une liste de len(ligne) + 1 entiers
  • les valeurs du triangle sont des entiers Python (aucune borne machine)

Solution

Exercice 1 - la moyenne pondérée

L’idée. Une moyenne pondérée, ce n’est pas la moyenne des notes : chaque note compte autant de fois que son coefficient. On prépare donc deux compteurs, l’un pour le total des note * coefficient, l’autre pour le total des coefficients, on parcourt le tableau une seule fois en les remplissant, et à la fin on divise le premier par le second.

Un exemple. Pour [(15.0, 2), (9.0, 1), (12.0, 3)], le premier compteur vaut 2*15 + 1*9 + 3*12 = 75 et le second 2 + 1 + 3 = 6, donc la moyenne est 75 / 6 = 12.5.

def moyenne(notes):
    somme_ponderee = 0
    somme_coefficients = 0
    for note, coefficient in notes:
        somme_ponderee = somme_ponderee + note * coefficient
        somme_coefficients = somme_coefficients + coefficient
    # notes est non vide : somme_coefficients est donc strictement positif
    return somme_ponderee / somme_coefficients

Chaque élément de notes est un couple : l’écriture for note, coefficient in notes range directement la première valeur du couple dans note et la seconde dans coefficient. Attention à la division : on veut un flottant (12.5), donc / et surtout pas //, qui donnerait 12. Comme le sujet garantit que notes n’est pas vide et que les coefficients sont strictement positifs, somme_coefficients n’est jamais nul : pas besoin de cas particulier.

Exercice 2 - le triangle de Pascal

L’idée. Tout le travail est dans ligne_suivante. Une ligne du triangle commence par 1, se termine par 1, et entre les deux chaque valeur est la somme de deux valeurs voisines de la ligne du dessus. On construit donc la nouvelle ligne en trois temps : on met le 1 du début, on ajoute toutes les sommes ligne[i] + ligne[i+1], puis on met le 1 de la fin. Ensuite pascal n’a plus qu’à partir de [[1]] et à appliquer ligne_suivante à la dernière ligne obtenue, autant de fois que nécessaire.

Un exemple. Pour ligne = [1, 3, 3, 1] : on part de [1], on ajoute 1+3 = 4, puis 3+3 = 6, puis 3+1 = 4, et enfin le 1 final, ce qui donne [1, 4, 6, 4, 1].

def ligne_suivante(ligne):
    '''Renvoie la ligne suivant ligne du triangle de Pascal'''
    ligne_suiv = [1]
    # chaque valeur intérieure est la somme de deux voisines de la ligne du dessus
    for i in range(len(ligne) - 1):
        ligne_suiv.append(ligne[i] + ligne[i + 1])
    ligne_suiv.append(1)
    return ligne_suiv

def pascal(n):
    '''Renvoie le triangle de Pascal de hauteur n'''
    triangle = [ [1] ]
    for k in range(n):
        ligne_k = ligne_suivante(triangle[k])
        triangle.append(ligne_k)
    return triangle

Le point délicat est le - 1 dans range(len(ligne) - 1) : comme on utilise ligne[i + 1], le dernier i autorisé est len(ligne) - 2, sinon on sortirait du tableau. On fabrique ainsi len(ligne) - 1 valeurs intérieures, plus les deux 1, soit bien une ligne de len(ligne) + 1 éléments.

Dans pascal, triangle contient déjà la ligne [1] au départ. La boucle tourne n fois et ajoute une ligne à chaque tour : le triangle final a donc n + 1 lignes, comme le demandent les exemples (pascal(2) renvoie 3 lignes, et pascal(0) renvoie [[1]] puisque la boucle ne tourne pas). Au tour numéro k, la dernière ligne construite est triangle[k] : c’est elle qu’on passe à ligne_suivante.