Initiation à la programmation ENSAE 1A

seance5_classe_method_cor.tex

classe CarreMagique


class CarreMagique :
    def __init__(self, coef) :
        self.mat = [ [ coef[i+j*3] for i in range(3) ] for j in range(3) ]
    def __str__(self) :
        return "\n".join ( [ ",".join( [ str(n) for n in row ] ) for row in self.mat ] )
    def __add__ (self, carre) :
        coef = []
        for i in range(3) :
            for j in range(3) :
                coef.append ( self.mat[i][j] + carre.mat[i][j])
        return CarreMagique(coef)

c = CarreMagique ( [ 1,3,4, 2,6,9, 8,7,5 ] )
print (c)
print (c + c)

fonction est_magique


Fonction \codes{est\_magique}:
class CarreMagique :
    def __init__(self, coef) :
        self.mat = [ [ coef[i+j*3] for i in range(3) ] for j in range(3) ]
    def __str__(self) :
        return "\n".join ( [ ",".join( [ str(n) for n in row ] ) for row in self.mat ] )
    def __add__ (self, carre) :
        coef = []
        for i in range(3) :
            for j in range(3) :
                coef.append ( self.mat[i][j] + carre.mat[i][j])
        return CarreMagique(coef)

    def somme_ligne_colonne_diagonale(self):
        tout = [ sum ( ligne ) for ligne in self.mat ] + \
               [ sum ( [ self.mat[i][j] for j in range(3) ] ) for i in range(3) ] + \
               [ sum ( [ self.mat[i][i] for i in range(3) ] ) ] + \
               [ sum ( [ self.mat[2-i][i] for i in range(3) ] ) ] 
        return tout
        
    def coefficient_unique(self): 
        d = { }
        for ligne in self.mat :
            for c in ligne :
                d [c] = d.get(c,0) + 1
        return len(d) == 9
        
    def est_magique(self):
        unique = self.coefficient_unique()
        if not unique : return False
        somme = self.somme_ligne_colonne_diagonale()
        return min(somme) == max(somme) 
        

c = CarreMagique ( [ 1,1,1, 1,1,1, 1,1,1 ] )
print (c.est_magique())
c = CarreMagique ( [ 1,4,8, 5,2,6, 7,9,3 ] )
print (c.est_magique())

tous les carrés, de façon naïve (1)


def tous_les_carre_naif() :
    res = []
    for a1 in range(9) :
        for a2 in range(9) :
            for a3 in range(9) :
                for b1 in range(9) :
                    for b2 in range(9) :
                        for b3 in range(9) :
                            for c1 in range(9) :
                                for c2 in range(9) :
                                    for c3 in range(9) :
                                        carre = CarreMagique( [a1,a2,a3, b1,b2,b3, c1,c2,c3 ])
                                        if carre.est_magique() :
                                            res.append (carre)
                                            print (carre)
    return res

tous les carrés, de façon naïve (2)


def tous_les_carre_naif2() :
    # on choisit l'ensemble de tous les tableaux de 9 chiffres compris entre 1 et 9
    coef = [ 1 ] * 9
    res = [ ]
    while coef [0] < 10 :
        carre = CarreMagique(coef)
        if carre.est_magique() :
            res.append (carre)
            print (carre)
        coef[-1] += 1
        if coef[-1] >= 10 :
            i = len(coef)-1
            while coef[i] >= 10 and i > 0 :
                coef[i] = 1
                coef[i-1] += 1
                i -= 1

tous les carrés, permutation


#coding:latin-1
def tous_les_carres_permutation( permut = None, pos = 0):
    if pos == 9 :
        carre = CarreMagique (permut) 
        if carre.est_magique() :
            print (carre)
            print ()
            return [ carre ]
        else :
            return []
    else :
        res = [ ]
        if permut == None :
            permut = [ i+1 for i in range(9) ]
        for i in range (pos,9) :
            # on permute les éléments i et pos
            a = permut[i]
            permut[i] = permut[pos]
            permut[pos] = a

            res += tous_les_carres_permutation(permut, pos+1)
            
            # on effectue la permutation inverse
            a = permut[i]
            permut[i] = permut[pos]
            permut[pos] = a
        return res
        
       
res = tous_les_carres_permutation()
print ("nombre de carrés", len(res))

mesure du temps d'exécution


import time
d = time.clock()    
res = tous_les_carres_permutation()
d = time.clock() - d
print ("nombre de carrés", len(res), " en ", d)

carré magique, réduction du nombre de permutations évaluées


def tous_les_carres_permutation_ligne12_meme_somme( permut = None, pos = 0):
    if pos == 9 :
        carre = CarreMagique (permut) 
        if carre.est_magique() :
            #print (carre)
            #print ()
            return [ carre ]
        else :
            return []
    else :
        if pos >= 6 :                                       # ajout
            if sum ( permut[:3]) != sum(permut[3:6]) :      # ajout
                return [ ]                                  # ajout
        
        res = [ ]
        if permut == None :
            permut = [ i+1 for i in range(9) ]
        for i in range (pos,9) :
            # on permute les éléments i et pos
            a = permut[i]
            permut[i] = permut[pos]
            permut[pos] = a

            res += tous_les_carres_permutation_ligne12_meme_somme(permut, pos+1)  # changé
            
            # on effectue la permutation inverse
            a = permut[i]
            permut[i] = permut[pos]
            permut[pos] = a
        return res

parcours des carrés magiques, version complète

#coding:latin-1
class CarreMagique :
    def __init__(self, coef) :
        self.mat = [ [ coef[i+j*3] for i in range(3) ] for j in range(3) ]
    def __str__(self) :
        return "\n".join ( [ ",".join( [ str(n) for n in row ] ) for row in self.mat ] )
    def __add__ (self, carre) :
        coef = []
        for i in range(3) :
            for j in range(3) :
                coef.append ( self.mat[i][j] + carre.mat[i][j])
        return CarreMagique(coef)
        
    def somme_ligne_colonne_diagonale(self):
        tout = [ sum ( ligne ) for ligne in self.mat ] + \
               [ sum ( [ self.mat[i][j] for j in range(3) ] ) for i in range(3) ] + \
               [ sum ( [ self.mat[i][i] for i in range(3) ] ) ] + \
               [ sum ( [ self.mat[2-i][i] for i in range(3) ] ) ] 
        return tout
        
    def coefficient_unique(self): 
        d = { }
        for ligne in self.mat :
            for c in ligne :
                d [c] = d.get(c,0) + 1
        return len(d) == 9
        
    def est_magique(self):
        unique = self.coefficient_unique()
        if not unique : return False
        somme = self.somme_ligne_colonne_diagonale()
        return min(somme) == max(somme) 
        
def tous_les_carres_permutation_ligne12_meme_somme( permut = None, pos = 0):
    if pos == 9 :
        carre = CarreMagique (permut) 
        if carre.est_magique() :
            #print (carre)
            #print ()
            return [ carre ]
        else :
            return []
    else :
        if pos >= 6 :                                       # ajout
            if sum ( permut[:3]) != sum(permut[3:6]) :      # ajout
                return [ ]                                  # ajout
        
        res = [ ]
        if permut == None :
            permut = [ i+1 for i in range(9) ]
        for i in range (pos,9) :
            # on permute les éléments i et pos
            a = permut[i]
            permut[i] = permut[pos]
            permut[pos] = a

            res += tous_les_carres_permutation_ligne12_meme_somme(permut, pos+1)  # changé
            
            # on effectue la permutation inverse
            a = permut[i]
            permut[i] = permut[pos]
            permut[pos] = a
        return res
        
import time
d = time.clock()    
res = tous_les_carres_permutation_ligne12_meme_somme()
d = time.clock() - d
print ("nombre de carrés", len(res), " en ", d)