views:

76

answers:

1

I'm trying to make a 4x4 sudoku solver in Python (I'm only a beginner!) and while trying to define a function to clean up my code somewhat, I ran across some strange behavior I don't really understand. Apparently, there's a difference between this:

sudoku = "0200140000230040"

sudoku = map(lambda x: '1234' if x=='0' else x, list(sudoku))
for i in range(16):
    for j in range(4):
        if sudoku[i] == str(j+1):
            for k in range(4):
                if len(sudoku[i/4*4+k]) > 1:
                    sudoku[i/4*4+k] = sudoku[i/4*4+k].translate(None, str(j+1))
            for k in range(4):
                if len(sudoku[4*k+i%4]) > 1:
                    sudoku[4*k+i%4] = sudoku[4*k+i%4].translate(None, str(j+1))

And this one:

sudoku = "0200140000230040"

def sd(l):
    for k in range(4):
        if len(sudoku[l]) > 1:
            sudoku[l] = sudoku[l].translate(None, str(j+1))

sudoku = map(lambda x: '1234' if x=='0' else x, list(sudoku))
for i in range(16):
    for j in range(4):
        if sudoku[i] == str(j+1):
            sd(i/4*4+k)
            sd(4*k+i%4)

The strange expressions are for checking the rows and columns (boxes aren't finished yet). I'm terribly sorry for wasting your time if this kind of thing has been asked already, but try running both code snippets and observing the different results you get. Thanks in advance.

(I have this weird feeling I'm going to get yelled at. Huh.)

+2  A: 

There is a difference... they fail with two different errors!

The first gives me this error:

  File "test.py", line 9, in <module>
    sudoku[i/4*4+k] = sudoku[i/4*4+k].translate(None, str(j+1))
TypeError: expected a character buffer object

The second gives me this error:

  File "test.py", line 12, in <module>
    sd(i/4*4+k)
NameError: name 'k' is not defined

I think the main problem is you assume that the expression tree for 'i/4*4+k' will be passed as a parameter to the function, but actually it is evaluated before the function call is made and this fails because k is not defined. You could use this instead:

    sd(lambda k: i/4*4+k)

and inside the function sd you can replace l with calls to l(k). Now you get the same error for both programs.

Mark Byers
Well, it didn't work that way, but I just noticed that -- indeed -- k isn't defined, so replacing " sd(i/4*4+k) sd(4*k+i%4)"with "for k in range(4): sd(i/4*4+k) sd(4*k+i%4) "and deleting the "for" in the function itself did the trick. Thanks.
nooodl
It `.translate(None)` doesn't work - you need to use `string.maketrans({})` to produce an identity table. But `.replace(str(j+1), '')` is simpler!
Beni Cherniavsky-Paskin