Sudoku solver

Marko Rauhamaa marko at pacujo.net
Wed Mar 25 07:39:26 EDT 2015


A lot of discussion was generated by the good, old fibonacci sequence. I
have yet to find practical use for fibonacci numbers. However, the
technique behind a sudoku solver come up every now and again in
practical situations.

I post below a sudoku solver. I eagerly await neater implementations (as
well as bug reports).

Usage:
========================================================================
./sudoku.py <sudoku.dat
========================================================================

sudoku.dat:
========================================================================
7 . . . . . 6 . .
. 2 . 8 . 6 . 7 .
. . . 4 3 . . 9 .
5 1 . . . . 4 . 3
. . 9 . . . . 1 .
. . . . 4 2 . . 5
. . . 9 . . . . 8
. . 6 . . . . 5 .
. . . . . . . 6 .
========================================================================

output:
========================================================================
7 8 4 2 9 5 6 3 1
9 2 3 8 1 6 5 7 4
6 5 1 4 3 7 8 9 2
5 1 8 6 7 9 4 2 3
2 4 9 3 5 8 7 1 6
3 6 7 1 4 2 9 8 5
1 7 5 9 6 3 2 4 8
8 3 6 7 2 4 1 5 9
4 9 2 5 8 1 3 6 7

========================================================================

sudoku.py:
========================================================================
#!/usr/bin/env python3

import sys

M = 3
N = M * M
Q = N * N

candidates = list(range(1, N + 1))

def main():
    board = []
    for n in sys.stdin.read().split():
        try:
            board.append(int(n))
        except ValueError:
            board.append(None)
    solve(board)

def solve(board, slot=0):
    if slot == Q:
        report(board)
    elif board[slot] is None:
        for candidate in candidates:
            if good(board, slot, candidate):
                board[slot] = candidate
                solve(board, slot + 1)
                board[slot] = None
    else:
        solve(board, slot + 1)

def good(board, slot, candidate):
    (shelf, row), (stack, col) = (divmod(x, M) for x in divmod(slot, N))
    for i in range(M):
        for j in range(M):
            if candidate in (board[(i * M + j) * N + stack * M + col],
                             board[(shelf * M + row) * N + i * M + j],
                             board[(shelf * M + i) * N + stack * M + j]):
                return False
    return True

def report(board):
    print("\n".join(
        " ".join(str(board[row * N + col])
                 for col in range(N))
        for row in range(N)))
    print()

if __name__ == '__main__':
    main()
========================================================================


Marko



More information about the Python-list mailing list