

Solving Every Sudoku Puzzle (2006) - srathi
http://norvig.com/sudoku.html

======
mdup
Another way to solve Sudoku is to understand that it is an instance of the
Exact Cover problem [1]. Basically, solving a 3x3 Sudoku grid is nothing more
than finding 9 "sheets" of each number which superimpose exactly on top of the
grid.

For example (2x2 sudoku = 4 sheets):

    
    
        1324
        3142 
        4213
        2431
    

is:

    
    
        1...   .2..   .3..   ...4
        .1..   ...2   3...   ..4.
        ..1. + .2.. + ...3 + 4...
        ...1   2...   ..3.   .4..
    

or even:

    
    
        x...   .x..   .x..   ...x
        .x..   ...x   x...   ..x.
        ..x. + .x.. + ...x + x...
        ...x   x...   ..x.   .x..
        x...   .x..   ..x.   ...x <- number row
    

where the last "number row" does not belong to the grid but serves to indicate
the number of the sheet.

This explains how sudoku relates to the Exact Cover problem. Now, there is a
good algorithm by Knuth to solve Exact Cover, which is known as Algorithm X
[2].

Algorithm X is just an algorithm but Knuth has also invented a very efficient
implementation of it, called Dancing Links or DLX for short [3]. DLX is
described in a very good and very readable paper by Knuth himself [4]. This is
one of the first serious papers I ever read and it was a real joy, mind-
opener.

[1]
[https://en.wikipedia.org/wiki/Exact_cover](https://en.wikipedia.org/wiki/Exact_cover)

[2]
[https://en.wikipedia.org/wiki/Knuth%27s_Algorithm_X](https://en.wikipedia.org/wiki/Knuth%27s_Algorithm_X)

[3]
[https://en.wikipedia.org/wiki/Dancing_Links](https://en.wikipedia.org/wiki/Dancing_Links)

[4] [http://www-cs-faculty.stanford.edu/~uno/papers/dancing-
color...](http://www-cs-faculty.stanford.edu/~uno/papers/dancing-color.ps.gz)

~~~
alxv
There is a very succinct implementation of Algorithm X in Python that uses a
variation of the Dancing Links approach.

[http://www.cs.mcgill.ca/~aassaf9/python/algorithm_x.html](http://www.cs.mcgill.ca/~aassaf9/python/algorithm_x.html)

[http://www.cs.mcgill.ca/~aassaf9/python/sudoku.txt](http://www.cs.mcgill.ca/~aassaf9/python/sudoku.txt)

------
justinator
Sudoku solver using Perl regex
[http://www.perlmonks.org/?node_id=471168](http://www.perlmonks.org/?node_id=471168)

Sudoku solver in three lines of Perl (golf):
[https://web.archive.org/web/20070106133158/http://www.eccles...](https://web.archive.org/web/20070106133158/http://www.ecclestoad.co.uk/blog/2005/06/02/sudoku_solver_in_three_lines_explained.html)

    
    
          use integer;@A=split//,<>;sub R{for$i(0..80){next if$A[$i];my%t=map{$_/9
        ==$i/9||$_%9==$i%9||$_/27==$i/27&&$_%9/3==$i%9/3?$A[$_]:0=>1}0..80;R($A[
        $i]=$_)for grep{!$t{$_}}1..9;return$A[$i]=0}die@A}R

------
wickawic
I've noticed that solving a sudoku is something of a rosetta stone for how
people program. Norvig's solution is very straightforward in hindsight, but I
think that code was either the result of many iterations or of a career of
making progressively more readable code.

Here are some other sudoku solvers that give more insight into the coder than
the problem:

Sudoku in APL:
[https://www.youtube.com/watch?v=DmT80OseAGs](https://www.youtube.com/watch?v=DmT80OseAGs)

Test driven sudoku:
[http://ronjeffries.com/xprog/articles/sudokumusings/](http://ronjeffries.com/xprog/articles/sudokumusings/)

~~~
amouat
A lot was discussed about Norvig's elegant solution compared to Ron Jeffries
effort and what it said about TDD:
[http://ravimohan.blogspot.co.uk/2007/04/learning-from-
sudoku...](http://ravimohan.blogspot.co.uk/2007/04/learning-from-sudoku-
solvers.html)

To be fair, the reason Norvig was so successful was he knew exactly the sort
of problem soduku was and how to solve it, whereas Ron lacked this background
knowledge.

~~~
romaniv
I think you're missing the point. TDD forces you to choose data
representations that best fit your tests. But in most cases of complex
programming you want to choose representations that reflect your current
understanding of the problem and then evolve them as your understanding
evolves.

In TDD your test will always predate your understanding. So it forces you to
solve (part of) the problem in your head first, rather than combine the act of
problem-solving and writing. And you do this over and over again. And when you
change your mind about something, you have twice the code to refactor.

It's a difference between _recording_ your thinking in code and actually
thinking in code.

This reminds me of an old article that exemplifies this:
[http://insideofthebox.tumblr.com/post/52002125683/prime-
fact...](http://insideofthebox.tumblr.com/post/52002125683/prime-factor-kata-
my-way)

Prime factor kata is often used as an introductory example of TDD, yet it is
clearly impractical and produces garbage code. Not to mention that I've
actually seen people do it, stumble, and hectically reach for their notes to
see what's the next step. And it's a pretty darn simple problem.

~~~
amouat
Err, I'm missing the point of my own point? You raise an interesting point,
but I don't think TDD was what stumped Ron. It's not a simple problem to solve
without a lot of thought unless you have the requisite background knowledge
like constraint problems. TDD did however have him going round in circles,
partly for the reasons you describe.

------
asgard1024
It has been shown in 2012 that you need at least 17 digits to uniquely specify
a Sudoku puzzle:
[http://www.math.ie/McGuire_V1.pdf](http://www.math.ie/McGuire_V1.pdf)

Their approach was quite close to _solving every sudoku puzzle_ , although
they traversed the space by the solutions.

------
yuchi
Small discovery: Brendan Eich implemented generators because he found them
incredibly important to translate this code in JS.

In fact in the ‘Translations’ section at the end there’s a link to this
Bugzilla ticket:
[https://bugzilla.mozilla.org/show_bug.cgi?id=380237](https://bugzilla.mozilla.org/show_bug.cgi?id=380237)

------
mythz
FWIW I've got benchmarks and ports of Norvig's sudoku solver in Python/PyPy,
Dart, C#, Ruby and CoffeeScript at:

[https://github.com/dartist/sudoku_solver](https://github.com/dartist/sudoku_solver)

------
mrspeaker
I love that this code is so elegant, but (and!) chooses strings and string
manipulation for storage of the possible cell values.

It seems like he started with lists and switched when he got to the search
method ("This is why I chose to implement the set of possible values for a
square as a string: I can copy values with values.copy() which is simple and
efficient.") - It's probably not an amazing insight, but I'm sure my brain
would have been yelling at me "don't use strings! don't use strings!".

------
deepaksurti
I implemented a solver in Common Lisp, quite a while back. The
repo:[https://github.com/dmsurti/sudoku](https://github.com/dmsurti/sudoku)
and some details here: [http://www.deepaksurti.com/blog/my-attempt-to-solve-
sudoku](http://www.deepaksurti.com/blog/my-attempt-to-solve-sudoku).

I was learning algorithms then and a sudoku solver was both fun and a good
learning exercise.

------
sadgit
Good time to pimp my c implementation of Norvig's algorithm:

[https://github.com/ssadler/ssadler-
various/blob/master/sudok...](https://github.com/ssadler/ssadler-
various/blob/master/sudoku-hammer/sudoku.c)

(This code is completely indulgent but very fast!)

------
discardorama
If someone is interested in seeing Sudoku solved in other languages, here's a
nice page:
[http://rosettacode.org/wiki/Sudoku](http://rosettacode.org/wiki/Sudoku)

Not all of the code is efficient, but it's interesting nevertheless.

------
thret
I feel like the 'search' function is missing the point. The sudoku puzzles are
generated in such a way that there is always a next move to be deduced: there
is never any need to guess. If you have to guess, then you have missed
something.

~~~
taeric
Depending on what you mean here, you are misrepresenting the problem. You may
not have to guess for what is a valid move that can be done on the board as it
is. But you do have to guess for a valid move that will lead you to a
completed board. Hence, you search among the possible moves for the one(s)
that will lead to a completed board state.

------
vtsrh
I find it rather disappointing that it still takes on the order of 10^2
milliseconds to solve the hardest sudokus.

This was tested with my own algorithm and one supposedly fast found online. I
will revise my code, but I doubt I will improve the speed.

------
JohnyLy
This is good to know that we can win Sudoku with a computer program but not
surprising. The goal of Sudoku is to make your intellect work and find logic
by yourself. The article should be named: How to win every Sudoku puzzle by
cheating.

~~~
informatimago
I never solved a single Sudoku. I never will. Instead, I wrote a Sudoku
solver.

What's better for the brain, solving Sudokus, or writing a Sudoku solver?

~~~
leni536
>What's better for the brain, solving Sudokus, or writing a Sudoku solver?

Both can be good. Chances are that your first Sudoku solver uses some
bruteforce approach, while your manual solution certainly does not. Then the
intuitions that you get from many manual games can drive the design of your
solver. Of course you can implement some established algorithm but I don't see
that challenging.

I have mathematician friend who won't ever play Nine Men's Morris because it's
a solved game, so it's not longer interesting for him. It's a shame, you can
learn a lot even playing Nim variants if you don't already know the winning
strategy, it's a good learning material for kids too.

