1

I've been learning programming and Python for about a month now using Udacity. For one of the questions we are supposed to write a function that checks if a sudoku list passed in is valid.

In the for loop below, I wanted to iterate through row and col at the same time with both the original and transposed list using zip() but mistakenly left in row in the second half of my or statement. I ran it and to my surprise, it still continued to return a correct answer.

def check_sudoku(array):  
    is_sudoku = True
    reference = range(1, len(array) + 1)
    transposed = zip(array)

    for row, col in zip(array, transposed):
        if sorted(row) != reference or sorted(row) != reference:
            is_sudoku = False
            break
    return is_sudoku

My guess is it's because I defined is_sudoku = True by default, and I'm comparing rows with a reference list so it catches invalid values even if my transpose didn't work. When I replaced the second row with col though, it broke.

My question is, is my guess right? If not, why does this code work and how could I better write this?

Thanks! (Pasted on codepad as well if you want to see what lists I passed in - http://codepad.org/IXDlZuUu)

poteto
  • 21
  • 2

1 Answers1

0

If the correct value was False, then your function works because at some point sorted(row) != reference. As for rewriting it, I'd think something like this would be more clear:

def check_sudoku(array):  
    reference = range(1, len(array) + 1)
    transposed = zip(array)
    for row, col in zip(array, transposed):
        if sorted(row) != reference or sorted(row) != reference:
            return False
    return True

Additionally, it's pretty hard for me to see why you do transposed = zip(array) and then zip(array, transposed). As far as I can tell that just takes a list like [1, 2, 3] and turns it into [(1, (1,)), (2, (2,)), (3, (3,))].

If you are looking to iterate through the rows and columns, here's one method that works.

>>> rows = incorrect
>>> cols = [[row[i] for i in range(len(rows[0]))] for row in rows]
>>> cols = [[row[i] for row in rows] for i in range(len(row))]
>>> cols
[[4, 6, 3, 9, 7, 8, 1, 5, 2], [1, 5, 9, 6, 3, 2, 4, 8, 7], [2, 8, 7, 4, 5, 1, 9, 3, 6], [3, 9, 5, 2, 1, 7, 6, 4, 8], [6, 4, 2, 3, 8, 9, 5, 7, 1], [7, 1, 8, 5, 4, 6, 3, 2, 9], [8, 3,
 1, 7, 6, 4, 2, 9, 5], [5, 2, 6, 8, 9, 3, 7, 1, 4], [1, 7, 4, 1, 2, 5, 8, 6, 3]]
>>> rows
[[4, 1, 2, 3, 6, 7, 8, 5, 1], [6, 5, 8, 9, 4, 1, 3, 2, 7], [3, 9, 7, 5, 2, 8, 1, 6, 4], [9, 6, 4, 2, 3, 5, 7, 8, 1], [7, 3, 5, 1, 8, 4, 6, 9, 2], [8, 2, 1, 7, 9, 6, 4, 3, 5], [1, 4,
 9, 6, 5, 3, 2, 7, 8], [5, 8, 3, 4, 7, 2, 9, 1, 6], [2, 7, 6, 8, 1, 9, 5, 4, 3]]
Nolen Royalty
  • 18,415
  • 4
  • 40
  • 50
  • Thanks. I used `zip(array, transposed)` after consulting the Python documentation for looping over 2 lists at the same time (http://docs.python.org/tutorial/datastructures.html#looping-techniques). My goal was to both check the rows and columns of the array, and I thought `transposed` would let me iterate through the list with just one `if` statement. – poteto Apr 13 '12 at 17:12
  • @poteto Well given that checking rows and checking columns are two different things, I don't think it makes a lot of sense to zip and compare like that. However, you could do `for row, col in zip(rows, cols):` using rows and cols from my example if you wanted to iterate over 1 row and 1 column at a time. Also it's worth noting that right now you are not verifying that the sudoku is valid, just that the numbers 1-9 are in each row and column. – Nolen Royalty Apr 13 '12 at 17:14
  • Thanks for the example! If every row and column contains 1-9 (no repetition or out of range numbers) then wouldn't the Sudoku be valid by definition? I can't think of a case where an invalid Sudoku would pass this test. – poteto Apr 13 '12 at 17:25
  • You aren't checking whether each 3x3 box contains the numbers 1-9. – Nolen Royalty Apr 13 '12 at 17:26
  • Ah yes I completely overlooked that. Thanks for pointing it out. – poteto Apr 13 '12 at 17:34
  • @poteto not a problem, if I have solved your issue then I'd appreciate it if you could accept my answer: it's a pretty standard response if your problem is solved. I noticed that you are new so I though I would say something ;) – Nolen Royalty Apr 13 '12 at 17:42