HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Check_sudoku in Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
check_sudokupythonstackoverflow

Problem

I have just started to learn programming with Python. I have been going through several online classes for the last month or two. Please bear with me if my questions are noobish.

One of the classes I am taking asked us to solve this problem.

# Define a procedure, check_sudoku,
# that takes as input a square list
# of lists representing an n x n
# sudoku puzzle solution and returns the boolean
# True if the input is a valid
# sudoku square and returns the boolean False
# otherwise.

# A valid sudoku square satisfies these
# two properties:

#   1. Each column of the square contains
#       each of the whole numbers from 1 to n exactly once.

#   2. Each row of the square contains each
#       of the whole numbers from 1 to n exactly once.

# You may assume the the input is square and contains at
# least one row and column.


After a while of trying to come up with the best code I can, this is what I ended up with.

def check_sudoku(sudlist):
    x = range(1, len(sudlist)+1) # makes a list of each number to be found
    rows = [[row[i] for row in sudlist] for i in range(len(sudlist))] # assigns all the rows to a flat list
    z = range(len(sudlist))
    for num in x:
        for pos in z:
            if num not in sudlist[pos] or num not in rows[pos]:
                return False
    return True


This code does work and passed all checks the class asked for. I just wonder what problems could the code have or how would you improve it?

I am just trying to improve by getting input from others. I appreciate any suggestions.

Solution

I would use set to do the checks, and you can build the columns using some zip magic:

def check_sudoku(sudlist) :
    numbers = set(range(1, len(sudlist) + 1))
    if (any(set(row) != numbers for row in sudlist) or
        any(set(col) != numbers for col in zip(*sudlist))) :
        return False
    return True


I have tested it with the following samples:

a = [[1, 2, 3, 4, 5],
     [2, 3, 5, 1, 4],
     [3, 5, 4, 2, 1],
     [4, 1, 2, 5, 3],
     [5, 4, 1, 3, 2]] # latin square

b = [[1, 2, 3, 4, 5],
     [2, 3, 5, 1, 4],
     [3, 5, 4, 2, 1],
     [4, 1, 2, 5, 3],
     [3, 4, 1, 5, 2]] # 1st and 4th elements of last row interchanged

c = [[1, 2, 3, 4, 5],
     [2, 4, 5, 1, 4],
     [3, 5, 4, 2, 1],
     [4, 1, 2, 5, 3],
     [5, 3, 1, 3, 2]] #1st and 5th elements of second column intechanged

>>> check_sudoku(a)
True
>>> check_sudoku(b)
False
>>> check_sudoku(c)
False

Code Snippets

def check_sudoku(sudlist) :
    numbers = set(range(1, len(sudlist) + 1))
    if (any(set(row) != numbers for row in sudlist) or
        any(set(col) != numbers for col in zip(*sudlist))) :
        return False
    return True
a = [[1, 2, 3, 4, 5],
     [2, 3, 5, 1, 4],
     [3, 5, 4, 2, 1],
     [4, 1, 2, 5, 3],
     [5, 4, 1, 3, 2]] # latin square

b = [[1, 2, 3, 4, 5],
     [2, 3, 5, 1, 4],
     [3, 5, 4, 2, 1],
     [4, 1, 2, 5, 3],
     [3, 4, 1, 5, 2]] # 1st and 4th elements of last row interchanged

c = [[1, 2, 3, 4, 5],
     [2, 4, 5, 1, 4],
     [3, 5, 4, 2, 1],
     [4, 1, 2, 5, 3],
     [5, 3, 1, 3, 2]] #1st and 5th elements of second column intechanged


>>> check_sudoku(a)
True
>>> check_sudoku(b)
False
>>> check_sudoku(c)
False

Context

StackExchange Code Review Q#22834, answer score: 8

Revisions (0)

No revisions yet.