Z3 parte 2 – Resolvendo Sudoku

Este é um artigo de continuação Para o primeiro artigo

Neste artigo vou ensiná-lo como resolver Sudoku usando Z3, a fim de resolver Sudoku ou qualquer outro desafio matemático você deve primeiro entender quais são as regras do desafio.

Depois de ter entendido as regras, você deve defini-las ao Z3 e ele próprio encontrará os números que se encaixam nessas regras.

Para baixar o código do artigo
Para baixar o exercício que apresentei no vídeo

Abaixo está um vídeo que demonstra como realizar o processo:

Então, se olharmos para o quadro sudoku do seguinte site:

Podemos dividi-lo nas seguintes 4 regras:

  • Em cada célula, devemos inserir um número de 1 a 9
  • Cada linha deve conter números únicos
  • Cada coluna deve conter números únicos
  • Cada pequeno quadrado de 3 por 3 deve conter números únicos

Agora vamos pegar essas regras e transformá-las em código, passo a passo.

Vamos começar definindo as variáveis:

As variáveis:

• game – Irá conter o jogo inteiro na lista sendo que cada célula do jogo é equivalente a uma linha no tabuleiro
• board_rules – Irá conter a regra de que cada célula deve ter um número entre 1 e 9
• row_rules – Irá conter a regra de que cada linha deve ser única
• column_rules – Irá conter a regra de que cada coluna deve ser única
• cube_3x3_rules – Irá conter a regra de que cada pequeno quadrado deve ser único

Uma vez definidas nossas variáveis, passaremos para a definição das regras, definiremos o jogo para conter as variáveis do tipo Int e definiremos que cada célula deve estar entre 1 e 9 usando and da seguinte maneira:

Para garantir que cada linha tenha números exclusivos, usaremos Distinct assim:

Para definir que cada coluna tenha números únicos iremos manter todos os números da coluna na variável auxiliar e a seguir iremos realizar Distinct de novo como fizemos anteriormente:

Passaremos à definição das regras do cubo pequeno de 3 por 3, para isso definiremos uma variável auxiliar que conterá todos os cubos:

Vamos agora definir uma série de condições que irão dividir todos os valores em-[game[x][y De acordo com os quadrados:

Depois de terminar de dividir todos os valores por suas posições em cubos, faremos Distinct em cada cubo individualmente e salvaremos o resultado em cube_3x3_rules.

Assim que terminarmos de definir todas as regras do jogo precisamos adicionar uma última regra que definirá nosso estado inicial no tabuleiro, para isso definiremos a variável auxiliar start_position_rules:

E vamos definir o estado inicial assim:

] Assim, vamos definir uma condição em Z3 usando If, a condição irá verificar se o valor no local -[game[x][y é 0, então não criaremos nenhuma outra regra se tivermos qualquer outro número, o valor no local-[game[x][y Deve ser igual a este número.

Agora precisamos adicionar todas essas regras ao Z3 Solver, que resolverá o sudoku para nós:

Verificaremos se as regras que definimos fazem sentido e se nosso sudoku pode ser resolvido e, em seguida, resolveremos o sudoku usando o model assim:

O resultado ficará assim:

Compartilhe este post

Outros artigos que você pode ter interesse: