RosettaCodeData/Task/Sudoku/PL-I/sudoku-1.pli
2015-02-20 00:35:01 -05:00

83 lines
2.4 KiB
Text

sudoku: procedure options (main); /* 27 July 2014 */
declare grid (9,9) fixed (1) static initial (
0, 0, 3, 0, 2, 0, 6, 0, 0,
9, 0, 0, 3, 0, 5, 0, 0, 1,
0, 0, 1, 8, 0, 6, 4, 0, 0,
0, 0, 8, 1, 0, 2, 9, 0, 0,
7, 0, 0, 0, 0, 0, 0, 0, 8,
0, 0, 6, 7, 0, 8, 2, 0, 0,
0, 0, 2, 6, 0, 9, 5, 0, 0,
8, 0, 0, 2, 0, 3, 0, 0, 9,
0, 0, 5, 0, 1, 0, 3, 0, 0 );
declare grid_solved (9,9) fixed (1);
call print_sudoku (grid);
call solve (1, 1);
put skip (2);
call print_sudoku (grid_solved);
solve: procedure (i, j) recursive options (reorder);
declare (i, j) fixed binary;
declare (n, n_tmp) fixed binary;
if i > 9 then
grid_solved = grid;
else
do n = 1 to 9;
if is_safe (i, j, n) then
do;
n_tmp = grid (i, j);
grid (i, j) = n;
if j = 9 then
call solve (i + 1, 1);
else
call solve (i, j + 1);
grid (i, j) = n_tmp;
end;
end;
end solve;
is_safe: procedure (i, j, n) returns (bit(1) aligned) options (reorder);
declare (i, j, n) fixed binary;
declare (true value ('1'b), false value ('0'b) ) bit (1);
declare (i_min, j_min, ii, jj) fixed binary;
declare kk bit(1) aligned;
if grid (i, j) = n then return (true);
if grid (i, j) ^= 0 then return (false);
if any (grid (i, *) = n) then return (false);
if any (grid (*, j) = n) then return (false);
/* i_min and j_min are the co-ordinates of the top left-hand corner */
/* of 3 x 3 grid in which element (i,j) exists. */
i_min = 1 + 3 * trunc((i - 1) / 3);
j_min = 1 + 3 * trunc((j - 1) / 3);
begin;
declare sub_grid(3,3) fixed (1) defined grid(1sub+i_min-1,2sub+j_min-1);
kk = true;
if any(sub_grid = n) then kk = false;
end;
return (kk);
end is_safe;
print_sudoku: procedure (grid);
declare grid (*,*) fixed (1);
declare ( i, j, ii) fixed binary;
declare bar character (19) initial ( '+-----+-----+-----+' );
declare frame (9) character (1) initial (' ', ' ', '|', ' ', ' ', '|', ' ', ' ', '|' );
put skip list (bar);
do i = 1 to 7 by 3;
do ii = i to i + 2;
put skip edit ( '|', (grid (ii, j), frame(j) do j = 1 to 9) ) (a, f(1));
end;
put skip list (bar);
end;
end print_sudoku;
end sudoku;