Implémentation de Supreme Solver dans Python 3

L'autre jour, en surfant sur le net, j'ai trouvé l'article suivant: "Le numéro le plus difficile au monde créé par un expert en mathématiques sur 3 mois" .. Que ce soit vrai ou non, j'ai essayé de résoudre ce problème avec Python3. La méthode backtrack est utilisée pour l'implémentation. En bref, cela signifie que vous résolvez par la force (´ ・ ω ・ `)


import itertools

class Sudoku(object):
    def __init__(self):
        self.matrix = [[0 for _ in range(9)] for _ in range(9)] #0 si vide
    
    #Résolvez un puzzle numéroté donné
    #Remplit les cellules vides les unes après les autres et renvoie True si toutes les cellules vides sont remplies.(Faux si non rempli)
    def solve(self):
        #Méthode d'élimination:Remplissez l'espace qui est décidé un seul
        while True:
            ls = []
            for i, j in itertools.product(range(9), repeat=2):
                if self.matrix[i][j] != 0: continue

                numbers = self.__find_numbers(i, j)
                if len(numbers) == 1: ls.append((i, j, numbers[0]))

            if len(ls) == 0: break
            for i, j, number in ls: self.matrix[i][j] = number


        blanks = [(i, j) for i, j in itertools.product(range(9), repeat=2) if self.matrix[i][j] == 0]
        if len(blanks) == 0: return True #Si tous les carrés sont déjà remplis

        first_i, first_j = blanks[0]
        stack = [(0, first_number) for first_number in self.__find_numbers(first_i, first_j)]

        #Méthode Backtrack:
        #     1.Mettez un nombre dans un espace vide
        #     2.Découvrez s'il y a un nombre dans la cellule vide suivante
        #     3. 2.Si vous n'entrez pas, revenez en arrière
        while stack:
            idx, number = stack.pop()
            i, j = blanks[idx]
            self.matrix[i][j] = number

            if idx == len(blanks) - 1: return True

            next_i, next_j = blanks[idx + 1]
            next_numbers = self.__find_numbers(next_i, next_j)

            #Piste arrière
            if len(next_numbers) == 0:
                stack_top_idx = stack[-1][0]
                for temp_idx in range(stack_top_idx, idx + 1):
                    temp_i, temp_j = blanks[temp_idx]
                    self.matrix[temp_i][temp_j] = 0

            stack.extend((idx + 1, next_number) for next_number in next_numbers)

        return False

    #Stocker le numéro qui peut être mis dans une certaine cellule dans l'ensemble
    def __find_numbers(self, i, j):
        used_numbers = set()
        #Examiner la même ligne et la même colonne
        for x in range(9): used_numbers |= {self.matrix[x][j], self.matrix[i][x]}

        #Examinez le même bloc
        box_i_min, box_j_min = (i // 3) * 3, (j // 3) * 3
        for box_i, box_j in itertools.product(range(box_i_min, box_i_min + 3), \
                                              range(box_j_min, box_j_min + 3)):
            used_numbers.add(self.matrix[box_i][box_j])

        return set(range(1, 10)) - used_numbers

    def __str__(self):
        return "\n".join("".join(map(str, row)) for row in self.matrix)

if __name__ == "__main__":
    matrix = '''
        ..53.....
        8......2.
        .7..1.5..
        4....53..
        .1..7...6
        ..32....8.
        .6.5....9
        ..4....3.
        .....97..
    '''.split()

    sudoku = Sudoku()
    for i, j in itertools.product(range(9), repeat=2):
        if matrix[i][j] == ".": continue
        sudoku.matrix[i][j] = int(matrix[i][j])
    
    print(sudoku)
    sudoku.solve()
    print("========")
    print(sudoku)


# 005300000
# 800000020
# 070010500
# 400005300
# 010070006
# 003200080
# 060500009
# 004000030
# 000009700
# =========
# 145327698
# 839654127
# 672918543
# 496185372
# 218473956
# 753296481
# 367542819
# 984761235
# 521839764

La réponse est la même que GIGAZINE, donc ça devrait aller (`・ ω ・ ´) Shakin

Recommended Posts

Implémentation de Supreme Solver dans Python 3
Allemand en Python
Implémentation de SimRank en Python
Implémentation de Shiritori en Python
Implémentation de la segmentation d'image en python (Union-Find)
Règles d'apprentissage Widrow-Hoff implémentées en Python
Implémentation de la méthode de propagation d'étiquettes en Python
Implémentation des règles d'apprentissage Perceptron en Python
Implémenté en 1 minute! LINE Notify en Python
Quadtree en Python --2
Python en optimisation
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Géocodage en python
SendKeys en Python
Un client HTTP simple implémenté en Python
Méta-analyse en Python
Unittest en Python
Implémenté en Python PRML Chapitre 7 SVM non linéaire
Époque en Python
Discord en Python
DCI en Python
tri rapide en python
N-Gram en Python
Programmation avec Python
J'ai essayé d'implémenter la régression logistique de Cousera en Python
Plink en Python
Constante en Python
FizzBuzz en Python
Sqlite en Python
Étape AIC en Python
Implémenté dans Python PRML Chapter 5 Neural Network
LINE-Bot [0] en Python
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
Mise en œuvre du tri Stuge dans Python 3 (tri à bulles et tri rapide)
Constante en Python
nCr en Python.
format en python
Scons en Python 3
Puyopuyo en python
python dans virtualenv
PPAP en Python
Implémenté en Python PRML Chapitre 1 Estimation bayésienne
Quad-tree en Python
Réflexion en Python
Chimie avec Python
Hashable en Python
DirectLiNGAM en Python
LiNGAM en Python
Aplatir en Python
Aplatir en python
Implémenté en Python PRML Chapitre 3 Régression linéaire bayésienne
J'ai essayé d'implémenter le filtre anti-spam bayésien de Robinson avec python
Implémenter la récurrence et l'exploration commémoratives dans Python and Go
Implémenté dans Python PRML Chapitre 1 Ajustement de courbe polygonale