I have been trying to write a program in Pascal (free pascal compiler, Lazarus IDE) that solves an uncompleted entered sudoku. I am moderately new to programming/pascal/lazarus, and so I have no idea how to use the debugging features. I have read through the code several times but I can't see what the problem is. Any help would be greatly appreciated!

program sudoku;

var
   input : array[1..9, 1..9] of integer;
   cell : array[1..9, 1..9, 1..9] of integer;
   output : array[1..9, 1..9] of integer;
   cposs : array[1..9, 1..9,  1..9] of integer;
   cloop, cloop2, rloop, rloop2, bloop, bloop2, loop, loop2, loop3, c, d : integer;
   cloop3, rloop3, bloop3 : integer;
   cloop4, rloop4, bloop4 : integer;
   cloop5, rloop5, bloop5 : integer;
   solved : boolean;

{$R *.res}

begin



     {sets all items of input array to 0}
     for loop := 1 to 9 do
       begin

            for loop2 := 1 to 9 do

                input[loop2,loop] := 0;
       end;

     {sets all items of cell array to 10}
     for loop := 1 to 9 do
       begin

            for loop2 := 1 to 9 do
              begin

                   for loop3 := 1 to 9 do
                   begin

                        cell[loop3,loop2,loop] := 10;
                   end;
              end;
       end;

     {instructions}
     writeln('== Sudoku Solver ==':50);
     writeln;
     writeln;
     writeln('Please enter the numbers of your sudoku from left to right, one row at a time from top to bottom, WITH A SPACE BETWEEN EACH CHARACTER, pressing enter after each row. If the cell is empty, please write a 0.');
     writeln;

     {reading inputs}
     for rloop := 1 to 9 do

       begin

          for cloop := 1 to 9 do

               read( input[cloop,rloop] );
       end;

     {copies inputs to "cell" array, and adds box position}
     for rloop := 1 to 9 do
         begin

            for cloop := 1 to 9 do
                begin

                   if cloop in [1..3] then
                            if rloop in [1..3] then
                              cell[cloop,rloop,1] := input[cloop,rloop] else

                            if rloop in [4..6] then
                              cell[cloop,rloop,4] := input[cloop,rloop] else

                            if rloop in [7..9] then
                              cell[cloop,rloop,7] := input[cloop,rloop];


                   if cloop in [4..6] then
                            if rloop in [1..3] then
                              cell[cloop,rloop,2] := input[cloop,rloop] else

                            if rloop in [4..6] then
                              cell[cloop,rloop,5] := input[cloop,rloop] else

                            if rloop in [7..9] then
                              cell[cloop,rloop,8] := input[cloop,rloop];

                   if cloop in [7..9] then
                            if rloop in [1..3] then
                              cell[cloop,rloop,3] := input[cloop,rloop] else

                            if rloop in [4..6] then
                              cell[cloop,rloop,6] := input[cloop,rloop] else

                            if rloop in [7..9] then
                              cell[cloop,rloop,9] := input[cloop,rloop];
                end;
         end;


     repeat


     c := 0;
     d := 0;

     {the big block}
     for bloop := 1 to 9 do
       begin
          for rloop := 1 to 9 do
           begin

             for cloop := 1 to 9 do
               begin

                 {checks if it is possible to have cell in that place
                  by checking if a value from input has been copied
                  over (the value wont be 10}
                  if cell[cloop,rloop,bloop] < 10 then
                  begin
                    if cell[cloop,rloop,bloop] > 0 then
                    begin

                      {no possibility for that number in the cells in this box}
                      for bloop2 := 1 to 9 do
                        begin

                          for rloop2 := 1 to 9 do
                            begin
                              for cloop2 := 1 to 9 do
                                begin
                                  if cell[cloop2,rloop2,bloop2] < 10 then
                                    begin
                                      if bloop2 = bloop then
                                        cposs[cloop2, rloop2, cell[cloop,rloop,bloop] ] := 1;
                                    end;
                                end;
                            end;
                        end;

                          {no possibility for that number in the cells in that row}
                          for bloop3 := 1 to 9 do
                            begin
                              for rloop3 := 1 to 9 do
                                begin
                                  for cloop3 := 1 to 9 do
                                    begin
                                      if cell[cloop3,rloop3,bloop3] < 10 then
                                        begin
                                          if rloop3 = rloop then
                                            cposs[cloop3, rloop3, cell[cloop,rloop,bloop] ] := 1;
                                        end;
                                    end;
                                end;
                            end;

                            {no possibility for that number in the cells in that column}
                            for bloop4 := 1 to 9 do
                              begin
                                for rloop4 := 1 to 9 do
                                  begin
                                    for cloop4 := 1 to 9 do
                                      begin
                                        if cell[cloop4,rloop4,bloop4] < 10 then
                                          begin
                                            if cloop4 = cloop then
                                              cposs[cloop4, rloop4, cell[cloop,rloop,bloop] ] := 1;
                                          end;
                                      end;
                                  end;
                              end;

                    end;

                  end;

                  {checks if cell has only one possible answer}
                  for loop := 1 to 9 do
                    begin
                         if cposs[cloop,rloop,loop] = 0 then
                            c := c + 1;
                    end;
                  if c = 1 then
                    begin
                         for loop := 1 to 9 do
                           begin
                           if cposs[cloop, rloop, loop] = 0 then
                             cell[cloop,rloop,bloop] := loop;
                           end;
                    end;
               end;
           end;
       end;
     {checks if sudoku is finished}
     for bloop5 := 1 to 9 do
       begin
         for rloop5 := 1 to 9 do
           begin
             for cloop5 := 1 to 9 do
               begin
                 if cell[cloop5, rloop5, bloop5] = 0 then
                   d := d + 1;
               end;
           end;
       end;
     if d = 0 then solved := true;

     until solved = true;

     {copying}
     for bloop := 1 to 9 do
       begin
         for rloop := 1 to 9 do
           begin
             for cloop := 1 to 9 do
               begin
                 if cell[cloop,rloop,bloop] < 10 then
                   begin
                     output[cloop,rloop] := cell[cloop,rloop,bloop];
                   end;
               end;
           end;
       end;

     writeln;

     {printing}
     for rloop := 1 to 9 do
       begin

         for cloop := 1 to 9 do
           begin

             write(output[cloop,rloop],' ');
           end;
         writeln;

       end;
     writeln;
     writeln('Solved!');
     readln;
     readln;
end.

If you input an unfinished sudoku then it seemingly gets stuck in an eternal repeat loop, exiting the loop works fine if you enter a solved sudoku which suggests that the problem is in the actual 'solving' section

I am not familiar with Lazarus, but I know you can executed the code line by line with the debugger. So, check the documentation and try that to search for the error. You do know that some solutions of a Sudoku require an (educated) guess. If I get some more time I will try your code in Delphi.

Can you in short describe the logic you are following to solve the puzzle (without code).

Edited 4 Years Ago by pritaeas

Sure, the basic idea behind the algorithm is that it goes through every inputed cell one by one, and if it has a number in that cell it will make it so that that number cannot be used in any of the cells in the box, row, or column that the original cell is in. Once it has done that for all the cells, it goes through each cell, and will check if there is only one possible number available for that cell and if there is it will set that cell to that number.

As mentioned, some solutions require guesses. In such situations, there will be a number of (logically related) cells that can have more than one value. Once your program encounters this, it will infinitely loop between those cells because it cannot find a single value for each cell.

Edited 4 Years Ago by scudzilla

This is true but no matter what sudoku you enter it doesn't work, I tried entering a complete sudoku with only one cell missing a value and it still didn't work

I suggest you read up on how to debug line by line, so you can exactly see what happens. I cannot guide you in that, because I do not use Lazarus.

We have Delphi at school, so any links/information on how to debug in that would be just as usefull and much appreciated!

This article has been dead for over six months. Start a new discussion instead.