-2

I saw a few sudoku solvers implementations ,but I cant figure out the problem in my code. I have a function sudokusolver which becomes sudoku Board and must return solved sudoku board.

def sudokutest(s,i,j,z):
    # z is the number
    isiValid = np.logical_or((i+1<1),(i+1>9));
    isjValid = np.logical_or((j+1<1),(j+1>9));
    iszValid = np.logical_or((z<1),(z>9));
    if s.shape!=(9,9):
        raise(Exception("Sudokumatrix not valid"));
    if isiValid:
        raise(Exception("i not valid"));
    if isjValid:
        raise(Exception("j not valid"));
    if iszValid:
        raise(Exception("z not valid"));

    if(s[i,j]!=0):
        return False;

    for ii in range(0,9):
        if(s[ii,j]==z):
            return False;

    for jj in range(0,9):
        if(s[i,jj]==z):
            return False;

    row = int(i/3) * 3;
    col = int(j/3) * 3;
    for ii in range(0,3):
        for jj in range(0,3):
            if(s[ii+row,jj+col]==z):
                return False;

    return True;

def possibleNums(s , i ,j):
    l = [];
    ind = 0;
    for k in range(1,10):
        if sudokutest(s,i,j,k):
            l.insert(ind,k);
            ind+=1;
    return l;

def sudokusolver(S):
    zeroFound = 0;
    for i in range(0,9):
        for j in range(0,9):
            if(S[i,j]==0):
                zeroFound=1;
                break;
        if(zeroFound==1):
            break;
    if(zeroFound==0):
          return S;

    x = possibleNums(S,i,j);
    for k in range(len(x)):
        S[i,j]=x[k];
        sudokusolver(S);
    S[i,j] = 0;

    return S;

sudokutest and possibleNums are correct , only sudokusolver give a RecursionError

S Hristoskov
  • 53
  • 1
  • 9
  • why in the sudokusolver are you using S[i,j] = 0;? and how are you building a matrix S[i,j] with Numpy or? – Marco smdm Dec 14 '16 at 12:02
  • Yes, with numpy and I use s[i, j]= 0 for backtracking when num isnt the right one – S Hristoskov Dec 14 '16 at 12:04
  • Ok...then to check I have to install numpy :-) let's see. To start your software then I need only s = numpy.zeros(shape=(9,9)) sudokusolver(s), correct? – Marco smdm Dec 14 '16 at 12:17
  • Try with this one S=np.matrix([0,0,0,0,0,9,0,7,8,5,1,0,0,0,0,0,6,9,9,0,8,0,2,5,0,0,0,0,3,2,0,0,0,0,0,0,0,0,9,3,0,0,0,1,0,0,0,0,4,0,0,0,8,0,8,0,0,0,9,0,7,0,0,6,0,1,0,0,0,0,0,0,0,0,0,0,7,0,8,0,1]).reshape((9,9)) – S Hristoskov Dec 14 '16 at 12:20
  • I used the one suggested and it is working :-) Have a nice day! – Marco smdm Dec 14 '16 at 12:49

1 Answers1

0

Finally I got to numpy up and running and I had to copy the number by hand (my problems). Anyway below a very simple solution. In your code (I modify a bit to understand the matrix) you have to find a proper way to stop the moment the Sudoku is completely solved. To do this I have used something really hard like sys.exit() but you can implement an additional check and move out of the whole loop after the matrix is completed. Otherwise you will write on top of the finished one with new zeros and you will run again and again same steps.

I have done only a small debug, but you can introduced additional print out and check how the matrix itself is evolving :-)

At least now is working and hope you will vote for my "short term" solution. Have a nice day and fun with your game!!

def sudokutest(s,i,j,z):
    # z is the number
    isiValid = numpy.logical_or((i+1<1),(i+1>9));
    isjValid = numpy.logical_or((j+1<1),(j+1>9));
    iszValid = numpy.logical_or((z<1),(z>9));
    if s.shape!=(9,9):
        raise(Exception("Sudokumatrix not valid"));
    if isiValid:
        raise(Exception("i not valid"));
    if isjValid:
        raise(Exception("j not valid"));
    if iszValid:
        raise(Exception("z not valid"));

    if(s[i,j]!=0):
        return False;

    for ii in range(0,9):
        if(s[ii,j]==z):
            return False;

    for jj in range(0,9):
        if(s[i,jj]==z):
            return False;

    row = int(i/3) * 3;
    col = int(j/3) * 3;
    for ii in range(0,3):
        for jj in range(0,3):
            if(s[ii+row,jj+col]==z):
                return False;

    return True;

def possibleNums(s , i ,j):
    l = [];
    ind = 0;
    for k in range(1,10):
        if sudokutest(s,i,j,k):
            l.insert(ind,k);
            ind+=1;
    return l;

def sudokusolver(S):
    zeroFound = 0;
    for i in range(0,9):
        for j in range(0,9):
            if(S[i,j]==0):
                zeroFound=1;
                break;
        if(zeroFound==1):
            break;
    if(zeroFound==0):
        print("REALLY The end")
        z = numpy.zeros(shape=(9,9))
        for x in range(0,9):
            for y in range(0,9):
                z[x,y] = S[x,y]
        print(z)
        return z


    x = possibleNums(S,i,j);

    for k in range(len(x)):
        S[i,j]=x[k];
        sudokusolver(S);
    S[i,j] = 0;


if __name__ == "__main__":
    import numpy 
    #s = numpy.zeros(shape=(9,9))

    k = numpy.matrix([0,0,0,0,0,9,0,7,8,5,1,0,0,0,0,0,6,9,9,0,8,0,2,5,0,0,0,0,3,2,0,0,0,0,0,0,0,0,9,3,0,0,0,1,0,0,0,0,4,0,0,0,8,0,8,0,0,0,9,0,7,0,0,6,0,1,0,0,0,0,0,0,0,0,0,0,7,0,8,0,1]).reshape(9,9)
    print(k)
    print('*'*80)
    sudokusolver(k)
Marco smdm
  • 1,020
  • 1
  • 15
  • 25
  • Interesting for you in case same initial numbers are used on the same line (I have not checked those impossible cases), but in a program there is always something to improve!!Ciao ciao – Marco smdm Dec 14 '16 at 12:50
  • Why do u use count and. Before that we have S[i,j] = 0; so next for loop I think is useless – S Hristoskov Dec 14 '16 at 12:54
  • The count was a leftover :-) sorry...you can completely remove. – Marco smdm Dec 14 '16 at 12:55
  • Ok I will try it and gove u a feedback. Btw is ur version returning the solved sudoku at the end? – S Hristoskov Dec 14 '16 at 13:00
  • [[ 3. 2. 4. 1. 6. 9. 5. 7. 8.] [ 5. 1. 7. 8. 3. 4. 2. 6. 9.] [ 9. 6. 8. 7. 2. 5. 1. 3. 4.] [ 1. 3. 2. 9. 8. 6. 4. 5. 7.] [ 4. 8. 9. 3. 5. 7. 6. 1. 2.] [ 7. 5. 6. 4. 1. 2. 9. 8. 3.] [ 8. 4. 3. 5. 9. 1. 7. 2. 6.] [ 6. 7. 1. 2. 4. 8. 3. 9. 5.] [ 2. 9. 5. 6. 7. 3. 8. 4. 1.]] This is the solution at your sudoku – Marco smdm Dec 14 '16 at 13:14
  • I have remove the sys.exit. The problem with your code is the recursion, You were always giving back the return S --> that is the original Matrix. It means you will always get the initial S. I am printing the z matrix that is the end one. Unfortunately you are in the middle of recursion so it will not return that value to the original parent. Do you agree? Is it now your sudoku complete? – Marco smdm Dec 14 '16 at 13:21
  • When I call the function with print(sudokusolver(S)) it gives me None instead of the right solved sudoku matrix – S Hristoskov Dec 14 '16 at 13:36
  • print(z) has to be correct. If you try to assign to sol = sudokusolver(S) then the print will be None, because no variable is return in the latest iteration. Could you please check that the print(z) is giving you the correct answer – Marco smdm Dec 14 '16 at 13:45
  • This is exercise for homework and it should be as defined (returns the solved sudoku) because it will be proved by tests – S Hristoskov Dec 14 '16 at 13:45
  • yes print(z) is giving the correct answer , I only have to make it so , that in end the solved sudoku to return and function will pass the tests – S Hristoskov Dec 14 '16 at 13:47
  • SO (Stack Overflow) is not the correct point for your homework. I just tried to reply where the soduku solution is going. The error is in the code itself. Your function is not returning anything. – Marco smdm Dec 14 '16 at 13:47
  • Anyway problem is with the line sudokusolver(S) the function itself is not returning a value!! You have to modify the software in a way that will return the matrix(z) that is indeed correct :-) – Marco smdm Dec 14 '16 at 13:49
  • Do u have any suggestion how can I fix that – S Hristoskov Dec 14 '16 at 13:52
  • You should do one operation after another and check every time a state is finished, if there are additional zero presents into the matrix. If not then you are there, otherwise iterate with the same functions. Your recursion is not clear and it is difficult to manage :-) Not sure if I get the time to modify your (I am at work). Hope this help and anyway I just replied above to your query regarding the solution of sudoku :) – Marco smdm Dec 14 '16 at 14:08