1

I am currently doing my first Python course and got the following exercise:

# THREE GOLD STARS

# Sudoku [http://en.wikipedia.org/wiki/Sudoku]
# is a logic puzzle where a game
# is defined by a partially filled
# 9 x 9 square of digits where each square
# contains one of the digits 1,2,3,4,5,6,7,8,9.
# For this question we will generalize
# and simplify the game.

# 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.

correct = [[1,2,3],
           [2,3,1],
           [3,1,2]]

incorrect = [[1,2,3,4],
             [2,3,1,3],
             [3,1,2,3],
             [4,4,4,4]]

incorrect2 = [[1,2,3,4],
             [2,3,1,4],
             [4,1,2,3],
             [3,4,1,2]]

incorrect3 = [[1,2,3,4,5],
              [2,3,1,5,6],
              [4,5,2,1,3],
              [3,4,5,2,1],
              [5,6,4,3,2]]

incorrect4 = [['a','b','c'],
              ['b','c','a'],
              ['c','a','b']]

incorrect5 = [ [1, 1.5],
               [1.5, 1]]

def check_sudoku():


#print check_sudoku(incorrect)
#>>> False

#print check_sudoku(correct)
#>>> True

#print check_sudoku(incorrect2)
#>>> False

#print check_sudoku(incorrect3)
#>>> False

#print check_sudoku(incorrect4)
#>>> False

#print check_sudoku(incorrect5)
#>>> False

My idea was to solve this by doing the following:

  1. First I need to append all columns to the list
  2. Then I can create an index starting from and check each element in sudoku as nested for loop with if soduko.count(index) != 1 --> return false

However, one sudoku is made up of letters in a string. I can't figure out what to do with that. I could convert each element in the list to ASCII with ord() and start the index from the ASCII code, in case of a = 97. This gives an error for numbers though. So before that I have to check if a list is either numbers or strings. How can I do that?

Thanks!

4
  • 1
    But the example correct and incorrect answers clearly demonstrate that the elements are numeric. Commented Oct 13, 2013 at 16:21
  • I don't get what you mean. incorrect4 is made up of strings, so I can't use the index to iterate through the list. Commented Oct 13, 2013 at 16:25
  • OK, but if the square contains any value that isn't an integer, it's invalid, right? So, exception handling? Commented Oct 13, 2013 at 16:26
  • Ah yeah, you are right. Still it would be nice to include cases where values arent integers, just for the sake of practice. I haven't done anything with exception handling yet. I am coming from C, so I thought it would be simple to just check if an element is a string, and if so, convert it to ASCII. Commented Oct 13, 2013 at 16:40

4 Answers 4

1

You can use

type('a') is str

or

isinstance('a', str)
Sign up to request clarification or add additional context in comments.

3 Comments

There's a big difference between type('a') is str and isinstance('a', str)... If you're going to offer both as a solution, it would be good to explain them...
Can anybody tell me why this doesn't change the str values at all: def check_sudoku(sudoku): for e in sudoku: for e in e: if type(e) == str: e = ord(e) return sudoku
@user2252633 - don't reuse variables: for item in sudoku: for i in item: if ...
1

As far as I understand it, if the input contains an element that is not an integer, you can be sure it's not a valid Sudoku square. So you don't need type checking:

def isValidSudokuSquare(inp):
  try:
    # .. validation that assumes elements are integers
  except TypeError:
    return False

(Aside/Hint: You can implement the rest of this validation in about two very readable lines of Python if you use sets.)

2 Comments

@MattDMo That's true, but I don't see how it relates to my answer. The question here is about converting types. A negative integer is an int, so solving that problem is out of scope.
I was thinking more along the lines of the two readable lines of Python, that's all
1

If items are strings, you can use the isdigit() and isalpha() methods. You'll have to verify that they are strings, otherwise you'll get an exception:

if all([isinstance(x, int) for x in my_list]):
    # All items are ints
elif all([isinstance(x, str) for x in my_list]):
    if all([x.isdigit() for x in my_list]):
        # all items are numerical strings
    elif all([x.isalpha() for x in my_list]):
        # all items are letters' strings (or characters, no digits)
    else:
        raise TypeError("type mismatch in item list")
else:
    raise TypeError("items must be of type int or str")

Comments

0
def check_sudoku( grid ):
    '''
    list of lists -> boolean

    Return True for a valid sudoku square and False otherwise.
    '''

    for row in grid:        
        for elem in row:
            if type(elem) is not int:
                return False # as we are only interested in wholes 
            # continue with your solution

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.