0

So, I'm trying to create a sudoku solver. Now, I want to check if a number is in it's line, column and square. Can I do it without introducing the line, column and square as function parameters? Is there any way to select the lists that contain an item? Here's my code:

sudoku = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
line1 = [sudoku[0],sudoku[1],sudoku[2],sudoku[3]]
column1 = [sudoku[0],sudoku[4],sudoku[8],sudoku[12]]
square1 = [sudoku[0],sudoku[1],sudoku[4],sudoku[5]]

def sudoku_cellsolver(x):
    while sudoku[x] == 0:
        number = sudoku[x]+1
        if number not in #"List, column, square":
            sudoku[x] = number
        else:
            number = number + 1
            #Check another time, etc
    while sudoku[x] != 0:
        sudoku_cellsolver(x+1)

Any help welcomed. I also have an error when the second branch gets out of range, but I will deal with it later.

EDIT:

Pseudocode:

sudoku = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
l1 = {sudoku[0],sudoku[1],sudoku[2],sudoku[3]}   #Converted to set
c1 = {sudoku[0],sudoku[4],sudoku[8],sudoku[12]}   #Converted to set
sq1 = {sudoku[0],sudoku[1],sudoku[4],sudoku[5]}   #Converted to set

group0 = [l1 | c1 | sq1]   #Concatenation of sets

def sudoku_cellsolver(x,group):
if sudoku[x] == 0:
    number = sudoku[x]+1
    if number not in group:
        sudoku[x] = number

The main problem is that I can't use a loop to solve one gap after another because I can't modify the parameter "group0" so that it changes to "group1" inside the function, something I can do with "sudoku[0]" to "sudoku[1]" using the "sudoku[x] = sudoku[x+1]".

If there's no way to change from "group0" to "group1" from inside the function, I'll have to define 16 almost-equal functions where only the "group" changes, and executing them from another function that uses an "if" statement to decide which one of the 16 functions is executed.

user3870619
  • 55
  • 1
  • 7

1 Answers1

1

Your line1, column1, and square1 variables look like they're defined at the global level, so you should be able to access them like any other variable. You're on the right track with the if thing not in list construct. Try concatenating the lists together to build one list that you can check for membership:

if number not in line1 + column1 + square1:
    sudoku[x] = number

This won't work for you if you need to be able to determine which of those lists number is in, but it doesn't look like you wanted to do that anyway.

If you want to modify your globals within a function, you will need to use the global keyword as described in this SO answer.

EDIT (based on comments)

It now appears that you're looking for the zip() function. Zip() groups elements from multiple iterables together by their index. Example:

a = [1,2,3]
b = [4,5,6]
c = [7,8,9]

groups = zip(a, b, c)

for i in xrange(3):
    print(groups[i])

Outputs this:

(1, 4, 7)
(2, 5, 8)
(3, 6, 9)

Can you use zip() to group your elements together?

Community
  • 1
  • 1
skrrgwasme
  • 9,358
  • 11
  • 54
  • 84
  • Okey, so I guess it's impossible to do what I wanted with a built-in method or something. It's not useful to concatenate them, as I would have to create a group for every cell. Well, I'll do it. Better 1 parameter than 3. I will declare sudoku "global", as you recommend me. Thank you for the help!! – user3870619 Jul 24 '14 at 17:54
  • You don't need to "declare" it as global, and there really is no such thing in Python. It just *is* global because of *where* it's defined. You only need to use the **global** keyword if you want to modify it from inside the function or have local variables of the same name. In your case though, you won't even need that. You can modify elements of a global list without the **global** keyword. You will only need it if you want to reassign the "sudoku" name to an entirely different object. – skrrgwasme Jul 24 '14 at 18:07
  • One more thought: you seem disappointed with my answer, and it sounds like I misunderstood what you were asking. You don't have to accept an answer just because it's the only one. You can always edit your question or leave additional comments to clarify what you're looking for. I based my answer on the pseudocode comment in your question. – skrrgwasme Jul 24 '14 at 18:12
  • Sorry, I'm quite newby :'). I've created the "group" that contains a concatenation of the line, column and square, turned this parameters into sets. Now I've found that I can't use this function as the global one as I can modify the parameter "group" inside the function (I would modify it so that when I change from sudoku[0] to sudoku[1], the group modified from group1 to group2, something impossible I think... Then I will use this function as a single use function within a bigger one. Now I realize I won't be able to modify the parameter "group" from within the bigger function. Any ideas? – user3870619 Jul 24 '14 at 18:15
  • No no, I'm pleased with it. I knew it was impossible to do what I wanted, but I was looking to see if there was a way to do it that I didn't know. Now I know there's not. – user3870619 Jul 24 '14 at 18:17
  • What you're looking for doesn't sound impossible. It may require a creative combination of **zip()** and maybe **operator.itemgetter()**, but not impossible in Python. Can you post a pseudocode description of your algorithm? I might see a path once I understand the overall approach better. Or can you link to an algorithm you're trying to implement that's described elsewhere? – skrrgwasme Jul 24 '14 at 18:29
  • Edited the post so that you see the code. This comment is just to notify it to you. – user3870619 Jul 24 '14 at 18:44
  • I'll save that function, seems smoother than mine. However, my very problem right now is about the parameters not being modifiable from inside the function. I'll just define it 16 times changing the name of the group and go with it. – user3870619 Jul 24 '14 at 19:25
  • Thank you so much for all your help, I would upvote if I had the rep. When I get to 15 rep, I'll. – user3870619 Jul 24 '14 at 19:26