4
\$\begingroup\$

My problem statement is:

Write a function to indicate if a given Sudoku board is legal. This function takes a Sudoku board (which you may assume is a N2xN2 2d list of integers, where N is an integer), and returns True if the board is legal, as described above.

And here's my solution:

import time, random

def solve_all(grids, name='', showif=0.0):
    """Attempt to solve a sequence of grids. Report results.
    When showif is a number of seconds, display puzzles that take longer.
    When showif is None, don't display any puzzles."""
    def time_solve(grid):
        start = time.clock()
        values = solve(grid)
        t = time.clock()-start
        ## Display puzzles that take long enough
        if showif is not None and t > showif:
            display(grid_values(grid))
            if values: display(values)
            print '(%.2f seconds)\n' % t
        return (t, solved(values))
    times, results = zip(*[time_solve(grid) for grid in grids])
    N = len(grids)
    if N > 1:
        print "Solved %d of %d %s puzzles (avg %.2f secs (%d Hz), max    %.2f secs)." % (
            sum(results), N, name, sum(times)/N, N/sum(times), max(times))

def solved(values):
    "A puzzle is solved if each unit is a permutation of the digits 1 to 9."
    def unitsolved(unit): return set(values[s] for s in unit) == set(digits)
    return values is not False and all(unitsolved(unit) for unit in unitlist)

def from_file(filename, sep='\n'):
    "Parse a file into a list of strings, separated by sep."
    return file(filename).read().strip().split(sep)

def random_puzzle(N=17):
    """Make a random puzzle with N or more assignments. Restart on contradictions.
    Note the resulting puzzle is not guaranteed to be solvable, but empirically
    about 99.8% of them are solvable. Some have multiple solutions."""
    values = dict((s, digits) for s in squares)
    for s in shuffled(squares):
        if not assign(values, s, random.choice(values[s])):
            break
        ds = [values[s] for s in squares if len(values[s]) == 1]
        if len(ds) >= N and len(set(ds)) >= 8:
            return ''.join(values[s] if len(values[s])==1 else '.' for s in squares)
    return random_puzzle(N) ## Give up and make a new puzzle

def shuffled(seq):
    "Return a randomly shuffled copy of the input sequence."
    seq = list(seq)
    random.shuffle(seq)
    return seq
\$\endgroup\$
  • 2
    \$\begingroup\$ Your code does not work as is, you seem to be using undeclared global variables everywhere, digits, squares, unitlist... Plus, none of the functions you have posted seem to do what your question says! \$\endgroup\$ – Jaime Jul 16 '15 at 16:36
  • \$\begingroup\$ Purists might also look for requirement for symmetry to be validated/enforced ? N^2 x N^2 ? If N > 3 then "digit" set will be larger than {1..9} ? \$\endgroup\$ – mckenzm Jul 26 '15 at 0:44
3
\$\begingroup\$

Coding style

Please follow PEP8, the style guide for Python code. As you read through it, you should recognize several coding style violations in your posted code. There is also a command line tool called pep8, which can check your entire project and report the violations. You can install it with:

pip install pep8

Strange condition

This looks very strange:

return values is not False and all(unitsolved(unit) for unit in unitlist)

From the posted code it's not clear what is the type of values. The plural name implies some kind of collection, but then it can never be False. As such, this condition doesn't make sense.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.