Adloun

Écrire somme ligne(m, i) et somme colonne(m, j)

Exercice d'entraînement · niveau 2 · NSI (première), chapitre 4 — Les types construits · Matrices

Énoncé

Écrire somme_ligne(m, i) et somme_colonne(m, j). Vérifier sur un exemple que la somme des sommes de lignes égale la somme des sommes de colonnes, et expliquer pourquoi c'est nécessairement le cas.

Corrigé


def somme_ligne(m, i):
    """Somme de la ligne i. Precondition : 0 <= i < len(m)."""
    assert 0 <= i < len(m)
    s = 0
    for x in m[i]:            # m[i] EST un tableau : parcours par element
        s = s + x
    return s

def somme_colonne(m, j):
    """Somme de la colonne j. Precondition : m non vide, 0 <= j < len(m[0])."""
    assert len(m) > 0 and 0 <= j < len(m[0])
    s = 0
    for i in range(len(m)):   # aucune ligne ne contient la colonne :
        s = s + m[i][j]       # il FAUT passer par les indices
    return s

Les deux fonctions ne se ressemblent pas, et c'est instructif. Une ligne est un objet concret — m[i] est un tableau, qu'on parcourt par élément. Une colonne n'existe nulle part : elle est répartie sur toutes les lignes, et il faut aller la chercher case par case. C'est une conséquence directe de la représentation « tableau de tableaux », et cela se paie : parcourir une colonne coûte plus cher que parcourir une ligne, dans tous les langages.

Vérification.


M = [[1, 2, 3], [4, 5, 6]]
[somme_ligne(M, i) for i in range(2)]        # [6, 15]
[somme_colonne(M, j) for j in range(3)]      # [5, 7, 9]

Somme des sommes de lignes : . Somme des sommes de colonnes : .

Pourquoi c'est nécessairement le cas. Les deux calculs additionnent exactement les mêmes nombres, dans deux ordres différents : par paquets de lignes d'un côté, par paquets de colonnes de l'autre. Comme l'addition est associative et commutative, le total ne dépend pas de l'ordre. Ce n'est donc pas une coïncidence à vérifier mais une identité à comprendre — les deux valent .


for _ in range(500):
    L, C = random.randint(1, 5), random.randint(1, 5)
    m = [[random.randint(-9, 9) for _ in range(C)] for _ in range(L)]
    assert sum(somme_ligne(m, i) for i in range(L)) \
           == sum(somme_colonne(m, j) for j in range(C))

Les matrices passent.

Une réserve honnête, de chapitre 2 : sur des flottants, l'addition n'est pas associative, et les deux totaux peuvent différer dans les derniers chiffres. Le raisonnement ci-dessus est exact sur les entiers ; sur les flottants, il faudrait comparer avec tolérance.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.