Search code examples
mathlogicsudokudiscrete-mathematicsmaple

Why do I cannot mutate a matrix in procedure?


My assignment is to solve a 4x4 sudoku puzzle by using Maple. I constructed a 4x4 matrix whose each element is a list. Each list contains numbers 1,2,3,4. My algorithm is to find a grid that only contains one number and use it to eliminate the same numbers in the lists in horizontal and vertical grids.

Here is my code: I used a procedure called removeElement to eliminate a number from a list, but it seems to be the same after the elimination. Is a matrix immutable? How to fix it? In addition, I used a counter called tester to check the program to see whether the matrix is changeable or not.

solveSudoku := proc(M)
local i; local j; local goAhead; local k; local index;
local tester; 
tester:=0;
while tester<10 do
    i:=1; j:=1;
    for i from 1 to 4 do
    for j from 1 to 4 do
       if(nops(M[i,j]) = 1) then 

            # The current matrix element has only one possibility 
            # cancel all possibilities in horizontal

            for k from 1 to 4 do
                #Every element of the matrix is a list
                #I was trying to remove a number from a list
                #the statement below DOES NOT remove number at all
                index:= hasElement(M[i,k],op(M[i,j]));

                if index <> -1 and k <> j then

                     removeElement(M[i,k],index);

                end if;
            end do:

            # now the horizontal numbers are eliminated 
            # cancel all possibilities in vertical
            k:=1;
            for k from 1 to 4 do
                index:= hasElement(M[k,j],op(M[i,j]));
                if index <> -1 and k <> i then

                   removeElement(M[k,j],index);

                end if;
            end do:

        end if;

    end do;
    end do;

    tester:=tester+1;
end do:

print (M);
end proc:

Here is the remove element procedure:

removeElement := proc(L,index)
    local boundary := index;
        if nops(L) <> 0 then
            return [op(1..boundary-1,L),op(boundary+1..,L)];
        end if;
    return [];
end proc;

Solution

  • List are immutable; matrices are mutable. To correct your code, you need to replace the line removeElement(M[k,j],index); with M[k,j]:= removeElement(M[k,j],index).

    There's no point in having a return value to a procedure if you just discard that value in the code that calls that procedure. That's what you were doing.