Carrés semi-magiques

Nous travaillons dans cet exercice sur des tableaux carrés d'entiers positifs.

Nous appelons un carré d'ordre \(n\) un tableau de \(n\) lignes et \(n\) colonnes dont chaque case contient un entier positif.

Carré semi-magique

Un carré est dit semi-magique lorsque les sommes des éléments situés sur chaque ligne, chaque colonne sont égales.

Exemples avec trois carrés

1 7
7 1

carre_2 est semi-magique car la somme de chaque ligne et de chaque colonne est égale à 8.

3 4 5
4 4 4
5 4 3

carre_3 est semi-magique car la somme de chaque ligne et de chaque colonne est égale à 12.

2 9 4
7 0 3
6 1 8

carre_3_bis n'est pas semi-magique car la somme de la première ligne est égale à 15 alors que celle de la deuxième ligne est égale à 10.

La classe Carre ci-après contient des méthodes qui permettent de manipuler des carrés.

  • La méthode __init__ permet de créer un carré sous forme d'un tableau à deux dimensions à partir d'un p-uplet d'entiers nombres. Nous remarquons que l'ordre du carré créé est la racine carré de la longueur du p-uplet passé en paramètre. Par exemple avec un p-uplet de taille 4, on crée un carré d'ordre 2, avec un de taille 9, un carré d'ordre 3.

  • La méthode affiche permet d'afficher le carré créé.

Exemples

🐍 Console Python
>>> nombres_3 = (3, 4, 5, 4, 4, 4, 5, 4, 3)
>>> carre_3 = Carre(nombres_3)
>>> carre_3.affiche()
[3, 4, 5]
[4, 4, 4]
[5, 4, 3]
  • La méthode somme_ligne prend en paramètre un entier i et renvoie la somme des éléments de la ligne i du carré.

Exemple

🐍 Console Python
>>> carre_3.somme_ligne(0)
12
  • La méthode somme_colonne prend en paramètre un entier j et renvoie la somme des éléments de la colonne j du carré.

Exemple

🐍 Console Python
>>> carre_3_bis.somme_colonne(1)
10
  • La méthode est_semi_magique renvoie True si le carré est semi magique, False sinon.

Exemples

🐍 Console Python
>>> carre_2.est_semi_magique()
True
>>> carre_3.est_semi_magique()
True
>>> carre_3_bis.est_semi_magique()
False
Question

Compléter le code ci-dessous, puis le tester sur les carrés carre_2, carre_3 et carre_3_bis.

###
# Testsbksl-nlbksl-nlnombrespy-und2 = (1, 7, 7, 1)bksl-nlnombrespy-und3 = (3, 4, 5, 4, 4, 4, 5, 4, 3)bksl-nlnombrespy-und3py-undbis = (2, 9, 4, 7, 0, 3, 6, 1, 8)bksl-nlnombrespy-und4 = (1, 2, 3, 4, 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34)bksl-nlcarrepy-und2 = Carre(nombrespy-und2)bksl-nlcarrepy-und3 = Carre(nombrespy-und3)bksl-nlcarrepy-und3py-undbis = Carre(nombrespy-und3py-undbis)bksl-nlcarrepy-und4 = Carre(nombrespy-und4)bksl-nlassert carrepy-und2.estpy-undsemipy-undmagique() is Truebksl-nlassert carrepy-und3.estpy-undsemipy-undmagique() is Truebksl-nlassert carrepy-und3py-undbis.estpy-undsemipy-undmagique() is Falsebksl-nlassert carrepy-und4.estpy-undsemipy-undmagique() is Falsebksl-nlbksl-nl# Autres testsbksl-nlbksl-nldef creepy-undmatrice(nombres):bksl-nl n = int(sqrt(len(nombres)))bksl-nl tableau = [[nombres[j + ipy-strn] for j in range(n)] for i in range(n)]bksl-nl return tableaubksl-nlbksl-nlnombrespy-und5 = (1, 4, 14, 15, 13, 16, 2, 3, 8, 5, 11, 10, 12, 9, 7, 6 )bksl-nlnombrespy-und6 = (1, 4, 14, 15, 13, 16, 2, 3, 8, 5, 11, 10, 12, 9, 7, 5 )bksl-nlnombrespy-und7 = (2, 4, 14, 15, 13, 16, 2, 3, 8, 5, 11, 10, 12, 9, 7, 6 )bksl-nlnombrespy-und8 = (1, 2, 3, 1, 2, 3, 1, 2, 3)bksl-nlnombrespy-und9 = (1, 1, 1, 2, 2, 2, 3, 3, 3)bksl-nlcarrepy-und5 = Carre(nombrespy-und5)bksl-nlcarrepy-und6 = Carre(nombrespy-und6)bksl-nlcarrepy-und7 = Carre(nombrespy-und7)bksl-nlcarrepy-und8 = Carre(nombrespy-und8)bksl-nlcarrepy-und9 = Carre(nombrespy-und9)bksl-nlbksl-nlfor nombres in [nombrespy-und2, nombrespy-und3, nombrespy-und4, nombrespy-und5, \bksl-nlnombrespy-und6, nombrespy-und7, nombrespy-und8, nombrespy-und9]:bksl-nl assert Carre(nombres).tableau == creepy-undmatrice(nombres), "méthode py-undpy-undinitpy-undpy-und fausse"bksl-nl bksl-nlassert carrepy-und5.estpy-undsemipy-undmagique() is Truebksl-nlassert carrepy-und6.estpy-undsemipy-undmagique() is Falsebksl-nlassert carrepy-und7.estpy-undsemipy-undmagique() is Falsebksl-nlassert carrepy-und8.estpy-undsemipy-undmagique() is False, "faux pour (1, 2, 3, 1, 2, 3, 1, 2, 3)"bksl-nlassert carrepy-und9.estpy-undsemipy-undmagique() is False, "faux pour (1, 1, 1, 2, 2, 2, 3, 3, 3)"bksl-nlbksl-nl# autres tests de Franckbksl-nlbksl-nlfrom random import randrangebksl-nlbksl-nln = 10bksl-nlbase = [randrange(10py-strpy-str9) for py-und in range(n)] py-str 2bksl-nlnombres = []bksl-nlfor i in range(n):bksl-nl nombres.extend(base[i:i+n])bksl-nlbksl-nlgrospy-undtest = tuple(nombres)bksl-nlassert Carre(grospy-undtest).estpy-undsemipy-undmagique() == True, "Erreur avec un gros test"bksl-nlbksl-nltruc = randrange(-10py-strpy-str8, 10py-strpy-str8)bksl-nltruc = 42 if not truc else trucbksl-nlbksl-nlfor i in range(n):bksl-nl for j in range(n):bksl-nl nombres[ipy-strn + j] += trucbksl-nl grospy-undtest = tuple(nombres)bksl-nl assert Carre(grospy-undtest).estpy-undsemipy-undmagique() == False, "Erreur avec un gros test"bksl-nl nombres[ipy-strn + j] -= trucbksl-nlbksl-nlfor kpy-unde in range(n - 1):bksl-nl for kpy-unds in range(kpy-unde + 1, n):bksl-nlbksl-nl for i in range(n):bksl-nl nombres[npy-stri + kpy-unds] += trucbksl-nl nombres[npy-stri + kpy-unde] -= trucbksl-nl grospy-undtest = tuple(nombres)bksl-nl assert Carre(grospy-undtest).estpy-undsemipy-undmagique() == False, "Erreur, il faut aussi vérifier les colonnes"bksl-nlbksl-nl nombres[npy-stri + kpy-unds] -= trucbksl-nl nombres[npy-stri + kpy-unde] += trucbksl-nlbksl-nl for j in range(n):bksl-nl nombres[n py-str kpy-unds + j] += trucbksl-nl nombres[n py-str kpy-unde + j] -= trucbksl-nl grospy-undtest = tuple(nombres)bksl-nl assert Carre(grospy-undtest).estpy-undsemipy-undmagique() == False, "Erreur, il faut aussi vérifier les lignes"bksl-nlbksl-nlbksl-nl 5/5
from math import sqrtbksl-nlbksl-nlclass Carre:bksl-nl def py-undpy-undinitpy-undpy-und(self, nombres):bksl-nl self.ordre = int(sqrt(len(nombres)))bksl-nl self.tableau = [[nombres[j + ipy-strself.ordre] for ... in range(self.ordre)] for ... in range(self.ordre)]bksl-nlbksl-nl def affiche(self):bksl-nl '''Affiche un carré'''bksl-nl for ligne in self.tableau:bksl-nl print(ligne)bksl-nlbksl-nl def sommepy-undligne(self, i):bksl-nl '''Calcule la somme des valeurs de la ligne i'''bksl-nl ...bksl-nlbksl-nl def sommepy-undcolonne(self, j):bksl-nl '''Calcule la somme des valeurs de la colonne j'''bksl-nl ...bksl-nlbksl-nl def estpy-undsemipy-undmagique(self):bksl-nl sommepy-undcommune = self.sommepy-undligne(0)bksl-nl ...bksl-nl bksl-nlbksl-nl# Testsbksl-nlbksl-nlnombrespy-und2 = (1, 7, 7, 1)bksl-nlnombrespy-und3 = (3, 4, 5, 4, 4, 4, 5, 4, 3)bksl-nlnombrespy-und3py-undbis = (2, 9, 4, 7, 0, 3, 6, 1, 8)bksl-nlnombrespy-und4 = (1, 2, 3, 4, 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34)bksl-nlcarrepy-und2 = Carre(nombrespy-und2)bksl-nlcarrepy-und3 = Carre(nombrespy-und3)bksl-nlcarrepy-und3py-undbis = Carre(nombrespy-und3py-undbis)bksl-nlcarrepy-und4 = Carre(nombrespy-und4)bksl-nlbksl-nlprint("Carré 4")bksl-nlcarrepy-und4.affiche()bksl-nlbksl-nlassert carrepy-und3.sommepy-undligne(0) == 12bksl-nlassert carrepy-und3py-undbis.sommepy-undcolonne(1) == 10bksl-nlassert carrepy-und2.estpy-undsemipy-undmagique() is Truebksl-nlassert carrepy-und3.estpy-undsemipy-undmagique() is Truebksl-nlassert carrepy-und3py-undbis.estpy-undsemipy-undmagique() is Falsebksl-nlassert carrepy-und4.estpy-undsemipy-undmagique() is Falsebksl-nlbksl-nlfrom math import sqrtbksl-nlbksl-nlclass Carre:bksl-nl def py-undpy-undinitpy-undpy-und(self, nombres):bksl-nl self.ordre = int(sqrt(len(nombres)))bksl-nl self.tableau = [[nombres[j + ipy-strself.ordre] for j in range(self.ordre)] for i in range(self.ordre)]bksl-nlbksl-nl def affiche(self):bksl-nl '''Affiche un carré'''bksl-nl for ligne in self.tableau:bksl-nl print(ligne)bksl-nlbksl-nl def sommepy-undligne(self, i):bksl-nl '''Calcule la somme des valeurs de la ligne i'''bksl-nl somme = 0bksl-nl for j in range(self.ordre):bksl-nl somme = somme + self.tableau[i][j]bksl-nl return sommebksl-nlbksl-nl def sommepy-undcolonne(self, j):bksl-nl '''Calcule la somme des valeurs de la colonne j'''bksl-nl somme = 0bksl-nl for i in range(self.ordre):bksl-nl somme = somme + self.tableau[i][j]bksl-nl return sommebksl-nlbksl-nl def estpy-undsemipy-undmagique(self):bksl-nl sommepy-undcommune = self.sommepy-undligne(0)bksl-nl for i in range(self.ordre):bksl-nl if self.sommepy-undligne(i) != sommepy-undcommune:bksl-nl return Falsebksl-nl for j in range(self.ordre):bksl-nl if self.sommepy-undcolonne(j) != sommepy-undcommune:bksl-nl return False bksl-nl return Truebksl-nlbksl-nlbksl-nl


Fonction sum

Nous aurions pu utiliser la fonction "built-in" sum de Python

sum

Réponses alternatives

Autre possibilité de réponses

🐍 Script Python
def somme_ligne(self, i):
    '''Calcule la somme des valeurs de la ligne i'''
    somme = sum(self.tableau[i])
    return somme

def somme_colonne(self, j):
    '''Calcule la somme des valeurs de la colonne j'''
    somme = sum([self.tableau[i][j] for i in range(self.ordre)])
    return somme