Generalized Sudoku (jigsaw sudoku)


Muita gente sabe o que é um sudoku: um puzzle com números que se joga numa tabela com $9$ linhas e $9$ colunas. O objetivo é simples: preencher a tabela com os números entre $1$ e $9$, seguindo umas quantas regras. As regras que devem ser seguidas não são complicadas, mas quem já experimentou resolver sudokus sabe que às vezes pode ser bastante difícil completar o puzzle!

Para além de resolver problemas, os matemáticos também gostam muito de generalizar. Suponhamos que temos uma série de características e que olhamos para todos os objetos que satisfazem essas restrições; uma generalização desses objetos pode ser dada ao ignorarmos uma das características consideradas.



Posto isto, uma generalização que pode ser feita dos puzzles de sudoku usuais é a forma das caixas: um tabuleiro de sudoku pode ser visto como um tabuleiro $3 \times 3$ onde cada célula é um quadrado também $3 \times 3$. Podemos alterar a forma dessas "caixas" mas manter as regras do sudoku: os números de $1$ a $9$ não podem estar repetidos nem nas linhas, nem nas colunas nem nas regiões (que já não são quadrados $3 \times 3$). No início do post há um exemplo de um puzzle de sudoku generalizado, incluímos agora outro:



Um amigo tem andado a resolver sudokus deste estilo e pediu-me que escrevesse um programa para verificar se estes puzzles têm solução única ou não. E eu escrevi! O programa é bastante simples e só precisa de dois ingredientes: um pouco de recursão e uma maneira de representar um tabuleiro de sudoku generalizado.

Contar soluções de um puzzle deste tipo é simples; varremos o tabuleiro de cima para baixo, da esquerda para a direita: quando estou a "olhar" para uma célula, vejo todas as opções que existem nessa célula, experimento uma, e vou preencher o resto do tabuleiro. Se a certa altura estiver a tentar preencher uma célula que não tem jogadas válidas é porque fiz um erro numa célula anterior e portanto tenho de andar para trás e tentar outras opções. Sempre que conseguir preencher o canto inferior direito, é porque encontrei uma solução válida para o puzzle. A título de exemplo incluo aqui a única solução encontrada para o puzzle que incluí em cima:

O código que conta as soluções pode ser encontrado aqui.
Everyone knows what a sudoku is: a puzzle with numbers played on a grid with $9$ rows and $9$ columns. The goal is simple: to fill the grid with the numbers from $1$ to $9$ whilst following some rules. Despite the rules being simple, even seasoned players know the puzzles sometimes can be quite tricky!

Besides problem solving, another thing mathematicians enjoy doing a lot is generalizing. Suppose we have a set of characteristics and then we consider all objects that have those characteristics. If we did not impose one of the characteristics we could say we have a generalization of our objects.



Having said that, we can easily generalize the sudoku puzzle: just allow the $3 \times 3$ boxes to have irregular shapes while having $9$ little squares. If we change those shapes, the rules now become: no repetitions per row, per column and per region. In the beginning we included an example of such a generalized grid, we include a different one here:



A friend of mine has been solving these puzzles and asked me to write a program to determine if a given puzzle has a unique solution or not. And so I did! The program is quite simple and uses just a bit of recursion on top of my representation of the non-square irregular regions.

Counting the solutions of these puzzles is straightforward; swiping the grid left to right, top to bottom: whenever I "look" at a given cell I just compute all possibilities, try one, and keep filling the grid. If I reach a point where a given cell has no legal plays, I must have made a mistake in some previous cell and I just undo my most recent guesses. Whenever I reach the bottom-right corner of the puzzle, it is because I was able to fill the grid completely. As an example I include the solution my program found for the last puzzle shown:

The code that computes the solutions can be found here.

Popular posts from this blog

Tutorial on programming a memory card game

Pocket maths: how to compute averages in your head

Markov Decision Processes 02: how the discount factor works