grid := [ [5, 3, 0, 0, 7, 0, 0, 0, 0], [6, 0, 0, 1, 9, 5, 0, 0, 0], [0, 9, 8, 0, 0, 0, 0, 6, 0], [8, 0, 0, 0, 6, 0, 0, 0, 3], [4, 0, 0, 8, 0, 3, 0, 0, 1], [7, 0, 0, 0, 2, 0, 0, 0, 6], [0, 6, 0, 0, 0, 0, 2, 8, 0], [0, 0, 0, 4, 1, 9, 0, 0, 5], [0, 0, 0, 0, 8, 0, 0, 7, 9] ]; # Returns a list of the x and y coordinates of an empty square in grid if some exist, -1 if none exist. findempty := proc(grid::list) local x, y; for x from 1 to 9 do for y from 1 to 9 do if grid[x][y]=0 then return[x, y] fi; end do; end do; return -1; end proc; # Returns a list of 1 if the corresponding index is allowed as a value of the empty square with empty x, y coordinates in grid, of 0 if it is not. findallow := proc(grid::list, empty::list) # Buffer iterates through forbidden values. local allow, i, buffer; allow := [1,1,1,1,1,1,1,1,1]; for i from 1 to 9 do # Lines buffer := grid[empty[1]][i]; if buffer <> 0 then allow[buffer] := 0 fi; # Columns buffer := grid[i][empty[2]]; if buffer <> 0 then allow[buffer] := 0 fi; # Squares buffer := grid[floor((empty[1]-1)/3)*3+1+floor((i-1)/3)][floor((empty[2]-1)/3)*3+1+((i-1) mod 3)]; if buffer <> 0 then allow[buffer] := 0 fi; end do; return allow; end proc; # Return a completed Sudoku grid out of grid, -1 if no possible completed grid exists. sksolve := proc(grid) local empty, allow, i, gridb, result; # Copy of grid because Maple does not allow editing of parameters. gridb:=grid; empty:=findempty(gridb); if is(empty, list) then # The grid is not completed allow := findallow(gridb, empty); for i from 1 to 9 do if allow[i]=1 then # If i is allowed for empty in grid, we use it. gridb[empty[1]][empty[2]]:=i; # We call the solving program recursively result:=sksolve(gridb); if is(result, list) then # The result is the completed grid, we return it return result fi; # If no completed grid has been found, we iterate. fi; od; # Nothing was found, return -1. return -1 else # The grid is completed, we return it. return gridb fi; end proc; # Return a completed Sudoku grid out of gridb, -1 if no possible completed grid exists. # Uses global variables to reduce memory usage. sksolve_global := proc() global gridb; local empty, allow, i, result; empty:=findempty(gridb); if is(empty, list) then # The grid is not completed allow := findallow(gridb, empty); for i from 1 to 9 do if allow[i]=1 then # If i is allowed for empty in grid, we use it. gridb[empty[1]][empty[2]]:=i; # We call the solving program recursively result:=sksolve_global(); if is(result, list) then # The result is the completed grid, we return it return result fi; # If no completed grid has been found, we iterate. fi; od; # Reset the current square gridb[empty[1]][empty[2]]:=0; # Nothing was found, return -1. return -1 else # The grid is completed, we return it. return gridb fi; end proc;